개요
Python 코드를 보다 보면 드물게 yield라는 키워드를 발견하게 된다. 관련 개념을 잘 알고 있지 않아 이번 글에서는 yield 키워드의 개념 및 역할 등에 대해 정리해보려고 한다.
제너레이터 (generator)
yield 키워드에 대해서 알기 전에 제너레이터(generator)라는 개념을 먼저 짚을 필요가 있다.
제너레이터는 필요한 데이터를 미리 만들어놓는 것이 아니라 필요할 때마다 하나씩 만들어내는 객체를 말한다.
호출할 때마다 값을 반환하기 때문에 처리에 필요한 시간이 길수록 한 번에 데이터를 반환하는 return보다 성능 측면에 이점을 가질 수 있다. 또한 return문은 모든 결괏값을 메모리에 올려야 하지만 제너레이터는 결괏값을 하나씩 메모리에 올려놓는다는 차이를 가진다.
이러한 특징으로 제너레이터는 게으른 반복자(lazy iterator) 또는 메모리를 효율적으로 사용하면서 반복을 수행하도록 돕는 객체라고 일컬어진다. 달리 말해 제너레이터는 내부적으로 __iter__ 함수를 가지고 있다는 의미다.
이러한 개념을 기억해두고 yield 키워드를 들여다보자.
yield
일반적으로 프로그래밍 언어에서 함수는 return 키워드를 이용해 값을 반환한다. Python도 동일하지만, return이 아니라 yield 키워드를 사용하면 조금 다른 방식으로 값을 반환할 수 있다.
간단한 예시와 함께 알아보자. 다음과 같이 알파벳 A, B, C를 반환하는 두 함수가 있다고 하자.
def return_abc():
return list('ABC')
def yield_abc():
for i in 'ABC':
yield i
먼저 두드러지는 차이는 return_abc는 한 번에 값을 반환하지만 yield_abc는 여러 번에 걸쳐 값을 반환한다는 점이다. 좀 더 명확하게 확인하기 위해 두 함수의 반환값을 출력해 보았다.
print(return_abc())
print(yield_abc())
return_abc는 리스트를, yield_abc는 제너레이터라는 것을 반환하는 것을 확인할 수 있다.
즉, Python에서 yield 키워드를 사용하면 제너레이터를 반환하게 된다.
yield 동작 방식
사전적으로 yield란 '양보하다'는 의미인데, Python에서는 함수를 호출할 쪽으로 프로그램의 제어권을 넘겨준다는 뜻으로 확장된다.
즉, yield 키워드에 의한 제너레이터를 순회하면 yield 키워드를 만날 때마다 값을 반환받고 함수가 잠시 중지된다. 즉, return과 다르게 함수가 끝나지 않는 상태로 대기하고 프로그램 제어권이 함수를 호출한 쪽으로 돌아온다.
위 그림은 함수와 제너레이터의 동작방식을 비교한 것이다.
참고 문서
https://www.daleseo.com/python-yield/