当Python解释器终止时,它会尝试按照以下顺序销毁对象:
- 执行已注册的
atexit
函数。 - 逐个销毁模块。在销毁模块时,解释器会将模块的全局变量设置为None。然而,如果存在其他对象仍然持有这些全局变量的引用,那么这些全局变量将不会被完全销毁,因为它们的引用计数不为0。
- 对于其他仍然存在的对象,解释器会尝试销毁它们。由于这些对象可能仍然持有全局变量的引用,因此在销毁这些对象时,它们所依赖的全局变量仍然存在。
然而在某些情况下,当解释器销毁模块时,可能会出现一些问题。例如,如果一个对象在其__del__
方法中引用了一个模块,那么在解释器销毁该模块时,可能会出现NameError异常。这是因为解释器在销毁模块时,会将模块的全局变量设置为None,而不是完全销毁它们。
个人认为这个机制是不合理的。任何工程启动服务的时候,要自底向上逐层启动;停止服务的时候,应当自顶向下释放资源
为什么Python解释器要首先销毁所有的模块和全局变量,然后再销毁对象?这样的话,上层对象中引用的一些底层全局依赖先被销毁,上层对象后被销毁,很容易引起奇奇怪怪的异常。。
为了避免这种问题,python只能通过一些强制手段或者兜底catch去保障解释器的“正常”结束:
- 使用
atexit
模块来注册一些在程序终止时执行的清理函数 - 在程序终止之前手动执行一些清理操作
- 在
__del__
方法中捕获可能出现的异常
网友评论