개발자 대부분은 이 프로세스를 제대로 설명하지 못한다. 얼핏 보면 제너레이터 함수 안에 위치한 yield 문장(그림 4-4의 좌측에 표현)이 산출(yielding)을 수행하는 것으로 보인다. 완전히 잘못된 표현은 아니지만 정확한 표현도 아니다.
제너레이터 함수는 이터레이터의 행위를 정의한다. 하지만 그림 4-4 우측에서 표현한 이터레이터 객체는 실제로 다음과 같이 동작한다.
함수에 yield 문장이 하나 이상 포함되면 그 함수는 더 이상 파이썬 기본 함수가 아니다. yield는 해당 함수가 값을 반환하지 않는 대신, next의 호출자(caller)에 값을 보내도록 유도한다. 상태 정보는 저장되며, next가 다시 호출되면 이터레이터는 처음부터 다시 시작하는 대신 시퀀스의 다음 값을 가지고 실행된다. 이 부분은 이해하기 쉽다.
하지만 사람들이 혼란스러워 하는 부분은 이 행위를 정의한 제너레이터 함수가 이 행위를 수행하는 것은 아니라는 점이다. 다행히도 여러분은 이 부분을 이해할 필요 없이 그냥 사용하면 된다. 자, 그럼 2부터 10까지 짝수만 출력하는 함수를 작성해 보자.
def print_evens():
for n in range(2, 11, 2):
print(n)
이제 print(n)을 yield n으로 변경해 보자. 그러면 함수 본연의 동작 방식이 바뀐다. 함수 이름도 make_evens_gen으로 변경하여 조금 더 명확하게 함수를 표현할 것이다.
def make_evens_gen():
for n in range(2, 11, 2):
yield n