为什么Python在对象之前销毁类变量?

Pet*_*ter 8 python destructor scope class

我知道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()
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

我理解如何正确清理Python对象的含义.但这种情况适用于类(我的C++朋友的共享或'静态')变量.当然实例有一个类变量的引用,不应该首先销毁它,因为我们仍然有引用它?

在类的对象之前将类销毁是一个问题还是错误?也许我的问题是"实际存储了类共享变量的位置?"

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

del a1
del a2
Run Code Online (Sandbox Code Playgroud)

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

Bre*_*arn 6

也许我的问题是"实际存储了类共享变量的位置?"

如果这是你的问题,那么答案是"在课堂上".

解决你的大问题:正如你所指出的,__del__不能依赖全局变量 - 但它A是一个全局变量,所以你不能依赖它.有趣的是,我无法在文档中找到关于此的官方声明,但互联网上有各种__del__不能使用全局变量的参考. 是一个:

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

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

  • 奇怪的是,当我用`.__ class__`尝试它时,我得到了同样的行为.在这种情况下调用`__del__`之前,似乎它也被设置为'None`,这有点令人惊讶. (2认同)
  • 通过环境设置"PYTHONVERBOSE = 2",您可以看到模块清理和属性清除的顺序. (2认同)