小编典典

__del__上的Python attributeError

python

我有一个python类对象,我想分配一个类变量的值

class Groupclass(Workerclass):
    """worker class"""
    count = 0

    def __init__(self):
        """initialize time"""
        Groupclass.count += 1
        self.membercount = 0;
        self.members = []

    def __del__(self):
        """delte a worker data"""
        Groupclass.count -= 1


if __name__ == "__main__":
    group1 = Groupclass()

该执行结果是正确的,但是有一条错误消息指出:

Exception AttributeError: "'NoneType' object has no attribute 'count'" in <bound method Groupclass.__del__ of <__main__.Groupclass instance at 0x00BA6710>> ignored

有人可以告诉我我做错了什么吗?


阅读 210

收藏
2020-12-20

共1个答案

小编典典

您的__del__方法假定该类在被调用时仍然存在。

这个假设是不正确的。Groupclass当您的Python程序退出时,已被清除,现在设置为None

测试是否仍然首先存在对该类的全局引用:

def __del__(self):
    if Groupclass:
        Groupclass.count -= 1

或用于type()获取本地参考:

def __del__(self):
    type(self).count -= 1

但是请注意,这意味着count更改的语义Groupclass是子类的(每个子类都有一个.count属性,而不是只有Groupclass一个.count属性)。

__del__挂钩文档中引用:

警告
:由于在不稳定的情况下__del__()调用方法,在执行过程中发生的异常将被忽略,并显示警告sys.stderr。同样,当__del__()响应于模块被删除而被调用时(例如,当执行程序时),该__del__()方法引用的其他全局变量可能已经被删除或正在被拆除(例如,进口机械关闭)
)。为此原因,__del__()方法应做到维持外部不变性所需的绝对最小值。从版本1.5开始,Python保证在删除其他全局变量之前,先从其模块中删除名称以单个下划线开头的全局变量。如果不存在对此类全局变量的其他引用,则这可能有助于确保在__del__()调用该方法时导入的模块仍然可用。

如果您使用的是Python 3,则还有两个附加说明:

  • CPython 3.3自动将随机哈希盐应用到字典中str使用的键globals;这也影响清理全局变量的顺序, 可能 是您仅在 某些 运行中看到了问题。

  • None根据安全对象完成,CPython 3.4不再将全局变量设置为(在大多数情况下);参见PEP 442

2020-12-20