예, GC가 전화를 걸고 있습니다 __del__
발전기의 정리 후크. GeneratorExit
발전기 기능에서 생성기를 종료하는 (호출로 generator.close()
).
이것은 컨텍스트 관리자를 의미합니다 __exit__
생성기 기능이 메모리에서 지워질 때마다 후크가 호출됩니다.
먼저 발전기를 직접 닫을 수 있습니다. generator.close()
:
b.close()
문제
발전기를 코 루틴으로 사용하여 작업 스케줄러와 같은 것을 만들고 있습니다. 아래 코드에서는 print cleanup
결정적으로.
가비지 수집가에게 물체를 공개하면 컨텍스트 관리자가 종료되는 것이 나의 상호 작용으로 보인다. 그러나 나는 GC의 타이밍에 의존하는 것보다 더 잘 알고 있습니다. 실제로 GC가 __exit__
아니면 또 다른 메커니즘입니까?
어떻게 엄격하게 힘을 줄 수 있습니까? print 'cleanup'
?
>>> from contextlib import contextmanager
>>> @contextmanager
... def foo():
... print 'setup'
... try:
... yield
... finally:
... print 'cleanup'
...
>>> def bar():
... with foo():
... while True:
... yield 'bar'
...
>>> b = bar()
>>> b.next()
setup
'bar'
>>> b = None
cleanup
해결책
예, GC가 전화를 걸고 있습니다 __del__
발전기의 정리 후크. GeneratorExit
발전기 기능에서 생성기를 종료하는 (호출로 generator.close()
).
이것은 컨텍스트 관리자를 의미합니다 __exit__
생성기 기능이 메모리에서 지워질 때마다 후크가 호출됩니다.
먼저 발전기를 직접 닫을 수 있습니다. generator.close()
:
b.close()
다른 팁
발전기가 종료되어야합니다. 발전기의 특성이 영원히 보는 경우 Gen.throw ()를 사용하여 발전기에서 예외를 제기 할 수 있습니다.
실제로, 나는 방금 생성기의 사양을 보았고, 정확히 이것을 수행하는 메소드 ()가 생성기 내부에서 generatorexit () 예외를 제기합니다. 따라서 당신이 그 일을 마치면 gen.close ()에게 전화하십시오. 모든 맥락 관리자는 자신을 호출합니다 출구 행동 양식. 발전기는 예외를 먹으므로 Close () 호출을 시도 블록으로 랩핑 할 필요가 없습니다.
>>> b= bar()
>>> b.next()
setup
'bar'
>>> b.close()
cleanup
>>>