【问题标题】:Why does Python destroy class variables before objects?为什么 Python 在对象之前销毁类变量?
【发布时间】:2013-03-02 07:37:24
【问题描述】:

我了解 Python 不保证程序结束时对象的销毁顺序,甚至不保证会发生。

所以我明白一个类的析构函数不能依赖全局变量,包括其他模块。

但我会认为类的对象必须在类被销毁之前被销毁。显然不是:

class A(object):
    count = 0
    def __init__(self):
        A.count += 1
        print 'Creating object, there are now', A.count
    def __del__(self):
        A.count -= 1
        print 'Destroying object, there are now', A.count

a1 = A()
a2 = A()

在 Windows 7 x64 Python v2.7.3 上,我得到:

Creating object, there are now 1
Creating object, there are now 2
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound
 method A.__del__ of <__main__.A object at 0x0234B8B0>> ignored
Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound
 method A.__del__ of <__main__.A object at 0x0234BE90>> ignored

我了解How do I correctly clean up a Python object? 的含义。但这种情况适用于类(我的 C++ 朋友的共享或“静态”)变量。实例肯定有对类变量的引用,不应该先销毁它,因为我们还有对它的引用?

在该类的对象之前销毁该类是问题还是错误? 也许我的问题是“类共享变量实际存储在哪里?”

(是的,我知道这可以使用上下文管理器来纠正,甚至可以简单地纠正:

del a1
del a2

在类被销毁之前销毁对象。)

【问题讨论】:

    标签: python class scope destructor


    【解决方案1】:

    也许我的问题是“类共享变量实际存储在哪里?”

    如果这是你的问题,答案是“在课堂上”。

    解决您更大的问题:正如您所指出的,__del__ 不能依赖全局变量 - 但 A 是全局变量,因此您不能依赖它。有趣的是,我在文档中找不到对此的官方声明,但互联网上有各种参考资料表明__del__ 不能使用全局变量。 Here是一:

    当 Python 程序终止时,每个模块中的全局变量都设置为 None。发生这种情况的顺序未定义

    如果您通过self.__class__.count 而不是A.count 访问计数,它将起作用。 (这也是你使用self.count时它起作用的原因。)

    【讨论】:

    • 实例上的.__class__ 怎么样?
    • @FatalError:你是对的,参考问题是一个红鲱鱼。问题不在于类本身已被删除,而是引用它的全局变量已设置为无。我编辑了我的答案。
    • 奇怪的是,当我尝试使用 .__class__ 时,我得到了相同的行为。在这种情况下,它似乎在调用__del__ 之前也设置为None,这有点令人惊讶。
    • @FatalError:您是否将-=print 都更改为使用self.__class__?我以为我也看到了你所看到的,但我还在做print A.count
    • 通过环境设置PYTHONVERBOSE=2可以看到模块清理和属性清理的顺序。
    猜你喜欢
    • 1970-01-01
    • 2019-11-10
    • 2012-08-27
    • 2012-01-30
    • 1970-01-01
    • 2015-07-26
    • 2014-09-24
    • 2015-05-13
    • 1970-01-01
    相关资源
    最近更新 更多