欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Python解释器的终止机制让人抓狂,2023年12月3日更新

最编程 2024-01-15 15:34:47
...

当Python解释器终止时,它会尝试按照以下顺序销毁对象:

  • 执行已注册的atexit函数。
  • 逐个销毁模块。在销毁模块时,解释器会将模块的全局变量设置为None。然而,如果存在其他对象仍然持有这些全局变量的引用,那么这些全局变量将不会被完全销毁,因为它们的引用计数不为0。
  • 对于其他仍然存在的对象,解释器会尝试销毁它们。由于这些对象可能仍然持有全局变量的引用,因此在销毁这些对象时,它们所依赖的全局变量仍然存在。

然而在某些情况下,当解释器销毁模块时,可能会出现一些问题。例如,如果一个对象在其__del__方法中引用了一个模块,那么在解释器销毁该模块时,可能会出现NameError异常。这是因为解释器在销毁模块时,会将模块的全局变量设置为None,而不是完全销毁它们。

个人认为这个机制是不合理的。任何工程启动服务的时候,要自底向上逐层启动;停止服务的时候,应当自顶向下释放资源

为什么Python解释器要首先销毁所有的模块和全局变量,然后再销毁对象?这样的话,上层对象中引用的一些底层全局依赖先被销毁,上层对象后被销毁,很容易引起奇奇怪怪的异常。。

为了避免这种问题,python只能通过一些强制手段或者兜底catch去保障解释器的“正常”结束:

  • 使用atexit模块来注册一些在程序终止时执行的清理函数
  • 在程序终止之前手动执行一些清理操作
  • __del__方法中捕获可能出现的异常