私はpython2.4で立ち往生しているので、ジェネレーターまたはでfinally句を使用できませんyield
。これを回避する方法はありますか?
Python 2.4でこの制限を回避する方法についての言及は見つかりません。また、私が考えた回避策(主に__del__
、妥当な時間内に実行されるようにすることを含む)の大ファンではありません。あまり魅力的ではありません。
私はpython2.4で立ち往生しているので、ジェネレーターまたはでfinally句を使用できませんyield
。これを回避する方法はありますか?
Python 2.4でこの制限を回避する方法についての言及は見つかりません。また、私が考えた回避策(主に__del__
、妥当な時間内に実行されるようにすることを含む)の大ファンではありません。あまり魅力的ではありません。
コードを複製して、finallyブロックを回避できます。
try:
yield 42
finally:
do_something()
になる:
try:
yield 42
except: # bare except, catches *anything*
do_something()
raise # re-raise same exception
do_something()
(Python 2.4でこれを試したことがないので、上記のre-raiseステートメントの代わりにsys.exc_infoを確認する必要があるかもしれませんraise sys.exc_info[0], sys.exc_info[1], sys.exc_info[2]
。)
ジェネレータインスタンスが単に放棄された(ガベージコレクションされた)ときに呼び出されることが保証されている唯一のコードは、__del__
そのローカル変数のメソッド(それらのオブジェクトへの参照が外部に存在しない場合)と、そのローカル変数への弱参照のコールバック(同上)です。非侵襲的であるため、弱参照ルートをお勧めします(__del__
弱参照可能なものだけで、特別なクラスは必要ありません)。例えば:
import weakref
def gen():
x = set()
def finis(*_):
print 'finis!'
y = weakref.ref(x, finis)
for i in range(99):
yield i
for i in gen():
if i>5: break
これは、必要に応じて印刷finis!
します。