예전에 PEP-340을 소개하는 글에서 약간 소개를 했던, 제너레이터 향상점들이 PEP-340이 빠진 이후에 PEP-342에 제너레이터 관련된 부분만 빠져나와서 들어오게 되었습니다. 수개월동안의 토론 끝에 방금 Phillip J. Eby씨가 구현한 것을 CVS에 넣어서 이제 큰 이변이 없는 한은, 파이썬 2.5의 가장 큰 변동사항으로 나가게 될 것 같네요.
PEP-342에서는 PEP-340에서처럼 우선 가장 큰 변경이 yield 키워드가 원래 statement였던 것이, expression으로 바뀌었다는 것입니다. 즉, 원래는 x = yield 0 이런 식의 표현이 금지되어 있다가, 이번부터는 아예 x = (yield 0) + (yield 1) 이런 것도 허용되게 되는 것! 그러니까.. 코루틴을 구현할 때 필수적이라고 할 수 있는 외부에서 중간에 인자를 던져주는 것이 가능하도록 되었습니다.
그래서 실제로 활용하는 방법을 보면,
|
>>> <b>def accum():</b> ... <b>sum = 0</b> ... <b>while True:</b> ... <b>sum += yield sum</b> ... >>> <b>a = accum(); a.next()</b> >>> <b>a.send(7)</b> 7 >>> <b>a.send(9)</b> 16 >>> <b>a.throw(KeyError, 5)</b> Traceback (most recent call last): File "", line 1, in ? KeyError: 5 |
여기서 새로 생긴 것이 바로 제너레이터의 send 메쏘드와 throw 메쏘드인데, send는 next에 인자를 추가한 것이라고 볼 수 있고, throw는 제너레이터가 멈춰있는 부분에서 예외를 발생시키는 역할을 합니다. 즉, 이제 Twisted의 deferred처리자를 완전히 제너레이터만 갖고도 깔끔하게 구현할 수 있게 되었습니다.! 꺅 만세
그 외에는, 제너레이터에 새로이 __del__이 생겨나고, cleanup이 지원되면서 try: finally: 안에다가 yield를 쓸 수 있게 되었습니다. 제너레이터가 중간에 그냥 멈춰버린 채로 해제됐을 때 자원 해제가 불가능했던 문제가 이것으로 해결됩니다.
일단은 많은 사람들이 오랫동안 토론해서 넣은 기능인 만큼, 잘 되었으면 좋겠는데, 개인적으로는 Twisted deferred가 이제 정말로 간단하게 제너레이터로 쓸 수 있게 되었다는 점이 가장 마음에 듭니다. 🙂