[python] python 웹 크롤링 기초

Get Current Working Directory 의 약자로, 파이썬 스크립트가 실행되고 있는 현재 폴더의 위치를 가져옴
os.getcwd();
with 구문
with open(TRTPOSE_TOPOLOGY, "r") as f:
human_pose = json.load(f)
python의 with 구문은 파일, 네트워크 연결, 데이터베이스 세션처럼 작업이 끝난 후 반드시 닫거나 정리 해야하는 자원을 안전하고 깔끔하게 관리하기 위해 사용하는 문법 입니다. C# 의 using() 구문과 같은 역할이라고 생각하면 되겠습니다.
내부에서는 다음과 같은 동작이 발생합니다.
f = open(TRIPOSE_TOPOLOGY, "r")
try:
human_pose = json.load(f)
finally:
f.close()
위 코드를 보면, with구문은 자동으로 자원을 해제하는 장점 뿐 아니라 예외가 발생했을때, 자동으로 자원을 해제하여 안전하게 프로그래밍을 할 수 있게 해줍니다.
threading.Event()
threading.Event()는 여러 스레드가 동시에 돌아가는 환경에서, 특정 스레드에게 “이제 그만 작동하고 멈춰라!” 하고 안전하게 신호를 보내는 ‘무선 스위치(또는 신호등)’입니다.
질문하신 코드의 stop_event라는 이름처럼, 보통 무한 루프를 돌며 열일하고 있는 백그라운드 스레드를 안전하게 종료(Stop)시키기 위한 목적으로 가장 많이 사용됩니다.
일반적인 파이썬 변수(예: is_running = True)를 사용해서 스레드를 멈추려고 하면, 여러 스레드가 한 변수에 동시에 접근할 때 값이 꼬이거나(동시성 이슈), 메모리 동기화 문제로 인해 한쪽 스레드가 바뀐 값을 제때 알아차리지 못하는 문제가 생길 수 있습니다.
threading.Event()는 파이썬 내부적으로 멀티스레드 환경에서도 절대로 데이터가 깨지지 않도록 안전하게 설계된(Thread-safe) 공식 신호기입니다.
이 객체는 내부적으로 눈에 보이지 않는 True / False 플래그(기본값은 False)를 가지고 있으며, 딱 3가지 명령어로 제어합니다.
-
clear(): 신호등을 빨간불(False)로 만듭니다. (초기 상태) -
set(): 신호등을 초록불(True)로 켭니다. (스위치를 누름) -
is_set(): 현재 신호등이 초록불(True)인지 빨간불(False)인지 확인합니다.
import threading
import time
# 1. 신호기(스위치) 생성 (기본값 False)
stop_event = threading.Event()
def worker_thread():
print("백그라운드 작업 시작...")
# 2. stop_event가 set(True) 되기 전까지 무한 반복
while not stop_event.is_set():
print("공장 가동 중... (데이터 처리 중)")
time.sleep(0.5)
print("정지 신호를 받았습니다. 안전하게 스레드를 종료합니다.")
# 스레드 틀어서 일 시키기
t = threading.Thread(target=worker_thread)
t.start()
# 메인 프로그램이 3초 동안 딴청 피우다가...
time.sleep(3)
# 3. 메인 스레드에서 스위치를 딸깍 누름 (True로 변경)
print("메인 스레드: 이제 그만 일해라! 스위치 ON")
stop_event.set()
global 변수
rollover_requested = False
def someFun1():
global rollover_requested
def someFun2():
global rollover_requested
파이썬에서 함수 내부에 global rollover_requested를 적는 것은 이 함수 안에서 rollover_requested 라는 변수를 읽거나 쓸 때, 함수 내부의 지역 변수를 만들지 말고 저 밖에 있는 공용 변수를 가르켜라라고 명시하는 것입니다.
따라서, someFun1()에 있는 global rollover_requested 와 someFun2() 에 있는 global rollover_requested는 중복된 글로벌 변수가 아닌, 전역으로 선언된 rollover_requested를 바라보라고 하는 것입니다.
환경변수 세팅
os.state(path)
stat = os.stat(csv_path)
csv_path 로 지정된 경로로 가서 해당 파일의 메타데이터를 읽어오는 함수 입니다. 파일의 용량, 마지막으로 수정된 시간 등 흔히 파일 속성에서 볼 수 있는 파일에 대한 데이터를 가져올 수 있습니다.
python *기호
C, Cpp 를 하다보면 * 라는 기호를 마주치게 되는데, Pointer라고 불리는 메모리 참조 연산자 입니다.
python에서는 조금 다르게 쓰입니다. 보통 string에 붙으며, Unpacking 이라고 부릅니다.
codec = "mp4v"
cv2.VideoWriter_fourcc(codec) # -> 에러 발생
위 코드처럼 mp4v 를 바로 넣으면 에러가 발생합니다. 해당 함수의 인자로는 “m”, “p”, “4”, “v” 의 총 4개의 인자가 들어오길 기대합니다. 물론, 인자로 4개를 하드코딩해서 넣어도 되지만, *를 사용하면 자동으로 하나씩 찢어져서 들어가게 됩니다.
codec = "mp4v"
cv2.VideoWriter_fourcc("m", "p", "4", "v") # 기대하는 인자, 하드코딩되어서 불편함
cv2.VideoWriter_fourcc(*codec) # 위와 동일한 코드, 편리함