您会看到
__del__某个地方的 钩子行为异常。
的
TypeError而被抛出 关闭 ,如解释器正在退出一切被删除,并且在一个引发的任何异常Python的
__del__解构钩被忽略了(但 是
打印的)。
在退出时,Python通过将所有内容重新绑定到来清除名称空间中的所有内容
None,但是未设置发生这种情况的顺序。
a.close()删除后,仍在运行的生成器将被关闭(称为),这会触发
GeneratorExit生成器中的异常,Python会对您的
exceptMyException:行进行测试。但是,如果
MyException有 已经 被清理和Python看到
exceptNone:了
TypeError被抛出,你看到那个消息打印。
您可以通过添加以下命令来触发错误,而无需退出Python:
MyException = Nonedel a
如果您使用
list(a)并使用了生成器的其余部分,或者
a.close()在Python退出和删除之前使用显式关闭了生成器
MyException,错误消息就会消失。
另一个解决方法是先处理
GeneratorExit:
def gen(): for i in range(3): try: yield i except GeneratorExit: return except MyException: print("MyException!")并且Python不会评估下一个
except处理程序。
该错误无法在Python
3.2或更早版本中重现,因此看起来哈希随机化(在Python 3.3中引入)随机化了清除顺序对象;这肯定可以解释为什么只在 某些
运行中看到错误,而在哈希顺序固定的早期Python运行中却看不到错误。
请注意,
.__del__()Python中的钩子与其他全局对象的交互在文档中以红色警告警告的形式进行了
.__del__()说明:
警告
:由于在不稳定的情况下__del__()调用方法,在执行过程中发生的异常将被忽略,并显示警告sys.stderr。同样,当__del__()响应于模块被删除而被调用时(例如,当执行程序时),该__del__()方法引用的其他全局变量可能已经被删除或正在被拆除(例如,进口机械关闭)
)。为此原因,__del__()方法应做到维持外部不变性所需的绝对最小值。从版本1.5开始,Python保证在删除其他全局变量之前,将从其下划线开头的全局变量从其模块中删除。如果不存在对此类全局变量的其他引用,则这可能有助于确保在__del__()调用该方法时导入的模块仍然可用。



