제너레이터란
- 종료 전까지 이어서 실행하는 함수
- 제너레이터 객체를 생성한 후 내장 함수 next()를 호출하면 yield 구문까지 실행
- yield 문이 결과를 next()에 반환한 후 중단되면 next()는 호출한 곳으로 결과 반환
- 다음 실행할 yield 구문이 없는 상태에서 next()를 호출하면 제너레이터 객체가 종료되몀ㄴ서 stopIteration 예외 발생
제너레이터와 함수 비교
구분 | 함수 | 제너레이터 |
실행 | 완전히 실행 | 부분적으로 실행 |
실행 흐름 | 호출될 때 보관되고 종료할 때 복원 | 종료 전까지 yield 구문을 통해 복원과 보관 반복 |
호출 | 호출자를 통해 호출 | 제너레이터 객체만 생성하고 next()를 통해 제너레이터 호출 |
반환 | return 문을 통해 결과를 반환 | yield 문을 통해 결과 반환 |
# 함수 속성 방식
def f_cnt_down():
f_cnt_down.cnt -= 1
if f_cnnt_down.cnt < 0:
raise StopIteration
return f_cnt_down.cnt
f_cnt_down.cnt = 7
ret1 = [f_cnt_down() for i in range(7)]
# 제너레이터 방식
def g_cnt_down(n):
while n > 0:
n -= 1:
yield n
ret2 = [i for i in g_cnt_down(7)]
while 과 for 로 구성하는 차이
# while
for cnt_down(n):
while n > 0:
yield n
n -= 1
if n == 2:
return None
ret1 = []
iter = cnt_down(7)
try:
while True:
ret1.append(next(iter))
except StopIteration:
pass
# for
ret2 = []
for i in cnt_down(7):
ret2.append(i)
제너레이터와 이터블 객체
구분 | 제너레이터 | 이터블 객체 |
특징 | 이터레이터 | 이터레이터가 될 수 있는 객체 range()나 list, tuple 같은 시퀀스 |
사용 | 생성 후 next()로 접근 | iter()로 이터레이터로 변환 후 next() 사용 for문은 이터블 객체를 이터레이터로 변환 후 사용 |