1

このコードが予想される出力「0 1 2 done」ではなく「2 1 0 done」を出力する理由を誰か説明できますか? 私が理解できるように、リスト内包表記中に作成されるいくつかの匿名変数があり、それらはリスト内包表記のカバー終了時に、フィロの原則を使用してガベージコレクションされます。しかし、それらはリスト aa で参照されていますね。その場合、2 番目の「del a」がdelマジック メソッドを呼び出さないのはなぜですか?

class A:
    def __init__(self, name):
        self.name = name
    def __del__(self):
        print self.name,

aa = [A(str(i)) for i in range(3)]
for a in aa:
    del a

print 'done'

また、高度な質問。http://codepad.org/niaUzGEyをご覧ください なぜ 5 部、3 部あるのですか? これは1枚じゃないの?なぜ5つか3つ?わからない、それが質問する理由です;)お時間をいただきありがとうございます!

4

2 に答える 2

7

delステートメントと__del__メソッドを混同しています。

del aa参照したオブジェクトから名前をバインド解除するだけです。によって参照されるリストaaは変更されないため、オブジェクトはすべて存在し続けます。

この__del__メソッドは、オブジェクトへの最後の参照が破棄された後にのみ呼び出されます。それは への呼び出しの後である可能性があります__del__が、通常はそうではありません。

を使用する必要はほとんどありませんdelaa再バインドするだけで、それに含まれるすべてのオブジェクトが解放され、別の方法で参照されていない場合は、それらの__del__メソッドが自動的に呼び出されることがはるかに一般的です。

また、使用する必要はほとんどありません__del__。ほとんどの場合、オブジェクトの Python の管理はクリーンアップを自動的に処理します。クラスにメソッドを追加する__del__ことは、ガベージ コレクターに干渉する可能性があるため、一般的には悪い考えです。そのため、むしろ逆説的__del__に、プログラムがメモリ リークを起こす可能性が高くなります。また、Python は__del__プログラムの終了時に が実際に呼び出されるかどうかを保証しません。もしそうなら、使用できないグローバル変数が存在しなくなっていることに気付くかもしれません。それを複数回呼び出します)。

要するに、__del__可能であれば使用を避けてください。

于 2012-05-17T12:01:46.103 に答える
3

done 2 1 0(CPython)を印刷します。

for ループではリスト要素を削除しません。それらは終了時に削除されます。私の知る限り、の呼び出し順序__del__は実装固有であるため、別の実装 (IronPython、Jython など) では異なる場合があります。

于 2012-05-17T11:45:58.213 に答える