【问题标题】:Python static variable deallocationPython静态变量释放
【发布时间】:2015-10-09 08:36:14
【问题描述】:

下面的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

【问题讨论】:

  • 对我来说不是重复的。另一个问题是关于circular references
  • 什么是“Python 静态变量”?这个概念存在吗?
  • 它适用于 Python 3.4

标签: python memory-management static


【解决方案1】:

因此,我们希望在删除 Bar class 时删除对 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")


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__

【讨论】:

  • 这并不能解释为什么它没有被删除。
  • 这是 Python 2.7 的一个特性,但我并不完全理解其设计原理。
  • 嗯 - 想多了,我想出了一个合理的解释
  • 你能解释一下循环引用在哪里吗?请详细说明你的最后一段。我不完全明白。
  • @A.P.好吧,我不确定 - 我是从 here 得到的。但我正在调查它。当然,所有类都有指向它们的元类的链接,并且一些元类有指向类的链接,但不确定是否全部都有?
猜你喜欢
  • 2011-01-26
  • 1970-01-01
  • 2011-11-11
  • 2011-12-18
  • 2011-07-30
  • 2013-02-09
  • 1970-01-01
  • 2021-11-17
相关资源
最近更新 更多