우선 Generator는 generator(iterator를 반환하기 위한 객체)를 생성해주는 함수!
그럼 iterator는 무엇이냐! iterator는 반복할 수 있는 객체의 요소를 리턴할 때 호출 한 시점에 값을 리턴하며 값을 지우고 그 상태를 유지해준다.
그러면 Yield는 무슨 관계가 있는데? yield는 generator를 만들때 함수 안에 yield를 삽입하면 yield를 만나는 순간 iterator 처럼 행동한다.
Generator 작동 순서
Step 1: Generator 메소드 호출 (Generator 객체 생성)
Step 2: 생성된 generator를 next함수로 호출
Step 3: yield까지 실행
Step 4: 첫번째 yield에서 중단(suspend)
Step 5: 호출자에게 expression_list 값을 반환(return)
Step 6: 중단된 지점에서 모든 상태가 보존(지역 변수들의 현재 연결들, 명령 포인터, 내부 연산 스택, 모든 예외처리)
Step 7: 1~5 step 반복
※ next함수 vs send함수 next함수를 통해 호출되면 return은 None, send함수를 통해 호출되면 return은 메소드로 전달된 값 {: .notice}
Generator랑 Coroutine과의 관계는? 둘이 같은건가?
우선 컴퓨터 프로그램에서 routine이라는 말을 자주 찾아 볼 수 있는데, 이때의 routine은 “어떤 일을 담당하는 하나의 정리된 일” 이라고 한다.
프로그램은 여러가지 routine을 조합하여 만들어지며, main routine과 sub routine으로 나눌 수 있다.
main routine은 프로그램의 주요한 부분이고 전체의 개략적인 동작 절차를 표시하도록 만들어진다.
sub routine은 사용빈도가 높고 자주 사용하는 부분을 모아 별도로 묶어 놓은 것으로 메인루틴을 보조한다. (메소로 묶음)
(서브루틴을 사용하면 함수호출시에만 저장된 메모리로 이동하기 때문에 메모리를 효율적으로 사용할 수 있다) 이제 진짜로 알아보려고 했던 Co-routine은 sub-routine과 비슷하다.
자주 쓰는 기능들을 별도의 공간에 모아 두었다는 점에서 서브루틴과 동일하지만, 코루틴은 yield까지 수행하고 상태를 중지한 후 메인루틴으로 돌아가 마치 동시에 실행되는 것처럼 작동한다. (co에서 볼 수 있듯 메인루틴과 협력관계임) 따라서 코루틴은 메인루틴에 종속적이지 않아 데이터를 주고 받을 수 있다! (이러한 특성때문에 send가 가능한 것임)
결국 Generator로 생성된 generator객체(iterator)는 co-routine과 같은 역할을 한다고 보면된다!