2012-01-26 3 views
3

Obj。 del()メソッド が呼び出されます。breakステートメントが発生したときのジェネレータの破棄

def my_integers(): 
    Obj = ExitObj() 
    i = 0 
    while(1): 
     yield i 
     i += 1 
def test_fun(): 
    for i in my_integers(): 
     if i > 3: 
      break 
anything_function() 
test_fun() 

私がテストを行なったし、OBJがちょうどbreak文の後に削除されるように見えた:anything_function前に()ループアウト。

これに依存して、ジェネレータ内部で定義されたオブジェクトの__ del__メソッドにループが残っているときにやりたいタスクをいくつか与えることができますか?

答えて

9

Obj.__del__()メソッドが呼び出されるタイミングを知りたいと思います。

できません。それは決してないかもしれない。 Pythonのファイナライザ(または実際の自動ガベージコレクタスキームを使用する環境)は、まったく動作することが保証されていないため、最終リゾートクリーンアップにのみ使用する必要があります。寿命を予測して管理する場合は、with statementcontext managersを使用してください。

class Foo(object): 
    def __enter__(self): 
     print 'Entered with block' 
    def __exit__(self, *exc_info): 
     print 'Exited with block' 
     return False 

with Foo(): 
    pass 
2

通常、デストラクタの呼び出し順序に依存することはできません。デストラクタは、ガベージコレクタがオブジェクトを再要求するときに呼び出されます。これは無期限に発生する可能性があります。例外が発生した場合にプログラムが終了すると、まったく発生しません。

オブジェクトのライフサイクルを決定的にする場合は、creating it inside a @contextmanager-decorated functionとし、withステートメントを使用します。ここで

0

は、Python言語の参照はobject.__del__(self)

x.__del__()試合言いたいことである - ... Xの参照カウントがゼロに達したときにのみ呼び出されます。オブジェクトの参照カウントがゼロになるのを防ぐ一般的な状況には、オブジェクト間の循環参照、例外をキャッチし、関数のスタックフレーム上のオブジェクトへの参照...

ですから、クリーンアップのために__del__に頼るべきではありません。コンテキストマネージャ(Cat Plus Plus mentions above)は正しい選択です。

関連する問題