Python静态变量释放

时间:2015-10-09 08:36:14

标签: python memory-management static

以下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

1 个答案:

答案 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__