1

__del__循環参照が関係している場合、カスタムメソッドが実行されないようです。

サンプルコードは次のとおりです。

class DelClass():
        def __init__(self,a):
            self.prop = a 

        def __del__(self):
            print 'del'



if __name__ == "__main__":

    dc1 = DelClass(None)
    dc2 = DelClass(dc1)#dc2 referring to dc1
    dc1.prop = dc2#dc1 referring to dc2, thus creating circular reference
    del dc1#not executing the custom __del__ method

    dc = DelClass(1)
    del dc#executing the custom __del__ method

なぜこれが起こるのですか?

編集: BrenBarn に感謝します。理由がわかりました。

del somethingの参照カウントをsomething1 減らすだけです。

__del__参照カウントが 0 に達した場合にのみ実行されます。

テストコードは次のとおりです。

import gc

class DelClass():
    def __init__(self,name,a):
        self.name = name
        self.prop = a

    def __del__(self):
        print '#####deleting',self.name

dc1 = DelClass("dc1",None)
dc2 = DelClass("dc2",dc1)#dc2 referring to dc1
dc1.prop = dc2#dc1 referring to dc2, thus creating circular reference
print "before deleting dc1,reference count:",len(gc.get_referrers(dc1))
del dc1#not executing the custom __del__ method
print "after deleting dc1, reference count:",len(gc.get_referrers(dc2.prop))
print "deleting the reference held by dc2"
del dc2.prop
print dc2

出力は次のとおりです。

before deleting dc1,reference count: 2
after deleting dc1, reference count: 1
deleting the reference held by dc2
#####deleting dc1
<__main__.DelClass instance at 0x9316dec>
#####deleting dc2

そして別の質問が表示されます:

出力の最後の行 ( #####deleting dc2) が発生するのはなぜですか?

いくつかの暗黙のdel操作が発生しますか?

4

4 に答える 4

3

およびガベージ コレクターのドキュメントを__del__参照してください。 おそらくあなたが思っていることをしませんし、しません。 を実行するときに必ずしも呼び出されるとは限らず、循環参照の場合には呼び出されない可能性があります。参照カウントを 1 減らすだけです。__del__del__del__deldel

于 2012-06-05T04:47:57.370 に答える
1

ガベージコレクタには、どちらを最初に安全に削除できるかを知る方法がないためです。

于 2012-06-05T04:46:58.447 に答える
1

このリンクを読んでください。これが役立つと思います。

del呼ばない__del__

delあなたが使用している方法で、ローカル変数を削除します。__del__オブジェクトが破棄されたときに呼び出されます。言語としての Python は、いつオブジェクトを破棄するかについて保証しません。

----更新編集----

に答えますSome implicit del operation happens?

このリンクを読むと役立ちます

__del__Python は、いつ呼び出されるか、または呼び出されるかどうかについて保証しません。そのままでは、__del__オブジェクトが参照サイクルの一部である場合、メソッドが呼び出される可能性はほとんどありません。サイクル全体がクリーンアップされたとしても、Python にはサイクルをどこで中断し、どの順序で__del__メソッドを実行するかを決定する方法がないためです (ある場合) を呼び出す必要があります。__del__のやや風変わりなセマンティクスのため (オブジェクトの refcount を呼び出すために一時__del__的に増加し、__del__メソッドは参照を別の場所に保存することでオブジェクトの破壊を防ぐことができます)、他の実装で起こることは少し面倒です。(現在の Jython の正確な詳細は覚えていませんが、過去に数回変更されています。)

つまり、CPython で__del__が呼び出されると、参照カウントがゼロになるとすぐに呼び出されます (__del__ メソッドを呼び出す唯一の方法は refcounting であり、CPython が呼び出す唯一の機会__del__は実際の refcount が変更されたときであるため)。

于 2012-06-05T05:25:34.910 に答える