작성 중...
1. decoration pattern, @ 사용.
호출부에서 read_batches(50) 시,
read_batches = mpgen(read_batches(50))
처럼 원 함수의
기능 확장.
2. python에서는 GIL문제로 thread 대신에 multiprocessing 사용.
mpgen을 통해 주 프로세스와는 별도의 데이터 생성 프로세스가 시작
Queue는 thread에서 데이터 공유에 사용(아래, 최대 3개까지의 item 저장 가능)
3. yield
함수의 형태를 가지는 iterator (generator, 생성기라고 부름)를 만들어 줌.
iterator란?
c = iter(range(5))
c.next(), c.next(),... # 0,1,2,...
함수의 인자를 비휘발성으로 만듬
함수 재호출 시, yield 다음이 수행
return은 결과값 반환, yield는 iterator 반환
4. functools.wraps:
디버깅 시 func.__doc__ 또는 func.__name__ 등의 속성을 요청 시
원 함수 read_batches의 속성이 안나오고 decoration된 mpgen함수의 속성이 나오는 것을 방지.
함수 속성을 인자인 원 함수 f로 되돌리는 역할.
데코레이터에서 closure문제 해결을 위해 사용.
def mpgen(f):
def main(q, args, kwargs):
try:
for item in f(*args, **kwargs):
q.put(item)
finally:
q.close()
@functools.wraps(f)
def wrapped(*args, **kwargs):
#*args(리스트 받고), **kwargs(map 받음)
q = multiprocessing.Queue(3)
proc = multiprocessing.Process(target=
main, args=(q, args, kwargs))
proc.start()
try:
while True:
item = q.get()
yield item
finally:
proc.terminate()
proc.join()
return wrapped
@mpgen
# mpgen의 인자함수로 read_batches을 사용함을 지정
def read_batches(batch_size):
def gen_vecs():
for im, c, p in gen.generate_ims(batch_size):
yield im, code_to_vec(p, c)
while True:
yield unzip(gen_vecs())
# yield는 휘발성이 없는 함수(iterator 만듬)