无法在__del __()中引用导入的模块

时间:2011-12-21 13:03:50

标签: python import del

我正在使用对象的__del__()取消订阅事件(使用类似于this的事件方案):

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

2 个答案:

答案 0 :(得分:7)

根据python doc about __del__

  

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

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

答案 1 :(得分:4)

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

您需要做的是确保在程序结束之前销毁需要调用__del__的对象 - 更好的是,然后使用__enter__和{{1}制作上下文管理器方法,然后在__exit__语句中使用。或者只是将with块中的子句包装在__del__块中,这样它们就不会引发异常 - 如果程序结束时代码的执行不重要。

相关问题