5
class Member(object):
    def __init__(self, identifier):
        self.identifier = identifier
        print "Member __init__", self.identifier

    def __del__(self):
        print "Member __del__", self.identifier
        with open("/home/might/" + self.identifier, "w") as outF:
            outF.write(self.identifier)

class WithMembers(object):
    def __init__(self):
        print "WithMembers __init__"
        print WithMembers.classMem
        self.instanceMem = Member("instance mem")

    def __del__(self):
        print "WithMembers __del__"

    classMem = Member("class mem")

if __name__ == "__main__":
    print "main"
    WithMembers()
    #del WithMembers.classMem       # "Member __del__ class mem" before "end"
    #del WithMembers                # "Member __del__ class mem" after "end"
    print "end"

上記のコードは Hidden.py にあり、実行python Hidden.pyすると次の出力が生成されます。

Member __init__ class mem
main
WithMembers __init__
<__main__.Member object at 0x935aeec>
Member __init__ instance mem
WithMembers __del__
Member __del__ instance mem
end

ステートメントのいずれかのコメントを外さない限りMember __del__ class mem、出力またはファイルには表示されません。どうしてこれなの?Python クラスとクラス属性のガベージ コレクションはいつ行われますか?class memdel

4

2 に答える 2

0

classMemclass のクラス変数ですWithMembers。これは、このクラスのすべてのインスタンスによって共有されることを意味します。これは Python のグローバルな機能です。そのため__del__、プログラムを終了するときにクラス Member が呼び出されませんでした。

__del__ここで質問があります: Python は、プログラムを終了するときに、すべての関数が呼び出されるように、すべての参照カウントを単純に 0 に設定しないのはなぜですか?

C++ と同様に、グローバル変数のデストラクタが呼び出されることを保証します。Python でこれを保証する唯一の方法は、すべてのモジュールを実行し、すべての変数を削除することです。しかし、これは、__del__変数がどの順序で削除されるかを知る方法がないため、使用したい可能性のあるグローバル変数がまだ存在することをメソッドが信頼できないことを意味します。

を強制的に破棄するには 2 つの方法がありますclassMem

一つはdel WithMembers.classMem。これにより、参照の数が 0 に減少し、__del__自動的に呼び出されます。

もう1つは、クラスWithMembersを古いスタイルのクラスにすることです(から継承していませんobject)。このような:

...

class WithMembers:
    def __init__(self):
        print "WithMembers __init__"
        print WithMembers.classMem
        self.instanceMem = Member("instance mem")
...        

出力は次のようになります。

Member __init__ class mem
main
WithMembers __init__
<__main__.Member object at 0x00000000026C5278>
Member __init__ instance mem
WithMembers __del__
Member __del__ instance mem
end
Member __del__ class mem

これは、この回答をよりよく理解するのに役立つ非常に便利なリンクです。 http://www.electricmonk.nl/log/2008/07/07/python-destructor-and-garbage-collection-notes/

それが役に立てば幸い。:)

于 2015-02-15T11:01:46.110 に答える