以下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()
输出是(Python 2.7):
Foo init running
Bar init running
Destructor Bar
我在期待:
Foo init running
Bar init running
Destructor Foo
Destructor Bar
答案 0 :(得分:3)
因此,当删除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
我得到了
Foo init running
Bar init running
Destructor Bar
Destructor Foo
你可以在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中。我提供了更多信息here。
编辑(有关循环引用的更多详细信息):
类包含循环引用,首先通过它们的字典:
MyClass.__dict__['__dict__'].__objclass__ == MyClass
其次是通过他们的MRO细节:
MyClass in MyClass.__mro__