A.P*_*.P. 6 python static memory-management
什么时候收集下面的python静态类变量垃圾?我期待从静态变量foo析构函数中看到消息.
class Foo(object):
    def __init__(self):
        print "Foo init running"
    def __del__(self):
        print "Destructor Foo"
class Bar(object):
    foo = Foo()
    def __init__(self):
        print "Bar init running"
    def __del__(self):
        print "Destructor Bar"
bar_obj = Bar()
Run Code Online (Sandbox Code Playgroud)
输出是(Python 2.7):
Foo init running
Bar init running
Destructor Bar
Run Code Online (Sandbox Code Playgroud)
我在期待:
Foo init running
Bar init running
Destructor Foo
Destructor Bar
Run Code Online (Sandbox Code Playgroud)
    因此,我们希望在删除类foo时删除对对象的引用。这通常就是发生的情况。如果你试试Bar 
class Foo(object):
    def __init__(self):
        print("Foo init running")
    def __del__(self):
        print("Destructor Foo")
class Bar(object):
    foo = Foo()
    def __init__(self):
        print("Bar init running")
    def __del__(self):
        print("Destructor Bar")
def f():
    bar_obj = Bar()
f()
del Bar
Run Code Online (Sandbox Code Playgroud)
我明白了
Foo init running
Bar init running
Destructor Bar
Destructor Foo
Run Code Online (Sandbox Code Playgroud)
您可以看到 Python 2.7 和 Python 3.4 中都调用了两个析构函数。然而,在Python 2.7中,Bar在程序关闭期间没有被正确破坏。正如文档所说:
不保证解释器退出时仍然存在的对象调用del () 方法。
为什么Bar解释器退出时不被破坏?
Python 2.7 中的类似乎不会因为循环引用而被破坏(见下文)。在 Python 3.4(PEP 442 之后)中,具有循环引用的对象会被可靠地破坏(即使它们有__del__方法),这可以解释这种变化。
然而,这并不能完全解释其中的差异,因为虽然类处于引用循环中,但类本身没有析构函数。
看起来,在 Python 2 中,具有循环引用的对象在解释器退出期间不会可靠地被破坏,而在 Python 3.4 中却是这样。我在这里提供更多信息。
编辑(有关循环引用的更多详细信息):
类包含对自身的循环引用,首先通过它们的字典:
MyClass.__dict__['__dict__'].__objclass__ == MyClass
Run Code Online (Sandbox Code Playgroud)
其次通过他们的 MRO 详细信息:
MyClass in MyClass.__mro__
Run Code Online (Sandbox Code Playgroud)