본문 바로가기

개발자 레니는 지금 -/소프트웨어와 함께

[ BASIC ] 발생자 제네레이터


Python

Generator

#Ubuntu 16.04 LTS

#Python 3.5.2



제네레이터

이터레이터를 생성해주는 함수이며 발생자라고 부르기도 한다.

이터레이터와 마찬가지로 모든 값을 다 반환하고 나면 StopIterater 예외를 발생시킨다.


재네레이터는 __iter__, __next__ 메소드를 가지고 있으며 yield라는 키워드를 사용한다.

재네레이터 객체에서 __next__ 메소드를 호출할 때마다,

재네레이터 함수 안의 yield까지 코드를 실행한 뒤 값을 반환하고 다음 __next__를 기다린다.


즉, yield를 사용하면 값을 제네레이터 함수는 yield 다음 코드 실행을 잠시 중단하고 함수의 바깥으로 값을 전달하면서 코드 실행을 함수 바깥에 양보하여 함수 바깥의 코드가 실행되도록 한다.


+ Tip

제네레이터 함수는 끝까지 도달하면 StopIteration 예외가 발생한다고 했다.

따라서 함수를 종료하는 return 키워드 발생시에도 StopIteration 예외가 발생한다.

특히 제네레이터 안에서 return에 반환값을 지정하면 StopIteration 예외의 에러 메시지로 return 값이 반환된다.


구현방법

이터레이터는 class에 __iter__, __next__ 또는 __getitem__ 메소드를 구현해야 하지만,

제네레이터 함수 안에서 yield라는 키워드만 사용해 주면 그 함수는 제네레이터 함수가 된다.


1. 한번에 한개의 값 전달

yield 반환할 값

예를 들어, yield x 이고, x = 10 이라면

10이라는 값을 반환하지만, 한 개 의 값이라서 반복되는 호출 __next(), next()를 사용할 수는 없다.


2. 한번에 여러개의 값 전달 Python 3.3 이상부터 가능

yield from 반복가능한 객체

yield from 이터레이터

yield from 제너레이터 객체

예를 들어, yield from [1, 2, 3]

리스트를 반환하게 되서 __next__(), next() 를 사용할 수 있게 된다.


제네레이터 표현식

리스트 표현식을 사용할 때는 [ ] 대괄호를 사용하지만, 제네레이터 표현식을 사용할 때는 ( ) 괄호를 이용한다.

리시트 표현식은 처음부터 리스트의 요소를 만들어내지만 제네레이터 표현식은 필요할 때 요소를 만들어내므로 성능이 더 좋고 메모리를 절약할 수 있다.


하지만 사용해본 결과,

인덱스를 지정해서 호출 할 수가 없기 때문에 순차적으로 증가하는 값만 필요하다면 사용하시고 인덱스를 사용해서 호출하셔야한다면 비추천합니다. 혹시 가능하다면 댓글로 알려주세요 :)





#2018년07월17일