6

我正在使用一个对象__del__()从事件中取消订阅它(使用类似于的事件方案):

import my_enviroment
class MyClass():
    def __del__(self):
        my_environment.events.my_event -= self.event_handler_func

奇怪的是,我在程序运行结束时收到以下错误:

Exception AttributeError: "'NoneType' object has no attribute 'events'" in <bound method MyClass.__del__ of <myclass.MyClass instance at 0x04C54580>> ignored

这怎么可能?!my_environment是我导入的模块,怎么会是None?(events是其中带有事件挂钩的全局对象,例如my_event

4

2 回答 2

7

根据python doc关于__del__

[...] 该方法引用的其他全局变量__del__()可能已经被删除或正在被拆除(例如,进口机器关闭)。出于这个原因,__del__()方法应该做维护外部不变量所需的绝对最小值。

换句话说,当__del__在您的对象上调用该方法时,my_enviroment可能已被python“删除”,所以它可以是 None ...

于 2011-12-21T13:10:01.837 回答
4

如果你查看 Python 的文档,你会看到当对象被终止时,在程序结束时,“机器”已经被反汇编了。这意味着您所依赖的大部分内容已经消失了——在这种情况下,带有模块引用的全局变量。

您需要做的是确保__del__在程序结束之前销毁需要调用的对象 - 更好的是,创建上下文管理器、with__enter____exit__方法,然后在with语句中使用 then。或者只是将你的子句包装__del__try-except块中,这样它们就不会引发异常——如果在程序结束时执行其中的代码并不重要。

于 2011-12-21T13:13:34.607 回答