제네레이터는 이터레이터를 생성해주는 함수다. 이터레이터는 클래스에 __iter__, __next__ 또는 __getitem__ 메서드를 구현해야하지만 제네레이터 함수 안에는 yield 라는 키워드만 사용하면 된다.

제네레이터와 yield 알아보기

함수 안에서 yield 를 사용하면 함수는 제네레이터가 되며 yield 에는 값(변수)를 지정한다.

def number_generator():
    yield 0
    yield 1
    yield 2

for i in number_generator():
    print(i)
0
1
2

제네레이터 객체가 이터레이터인지 확인하기

dir 함수로 메서드 목록을 보고 __iter__, __next__ 메서드가 있는지 확인해보자.

['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', 
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
 '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', 
'__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 
'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']

for와 제네레이터

for문에서 제네레이터는 다음과 같이 동작한다.

yield에는 '생산하다'라는 뜻과 '양보하다'라는 뜻이 있다. yield는 값을 함수 밖으로 반환하면서 현재 함수를 잠깐 중단하고 바깥의 코드가 실행되도록 한다.

yield의 동작 과정을 알아보기

__next__ 메서드를 직접 호출해보자.

def number_generator():
    yield 0
    yield 1
    yield 2

g = number_generator()

a = next(g)
print(a)

a = next(g)
print(a)

a = next(g)
print(a)
0
1
2

yield를 사용하여 바깥으로 전달한 값은 next함수(__next__) 메서드의 반환값으로 나온다.