Python解释器退出时不会被销毁的对象有哪些?
__del__()的常见场景 带自定义
__del__()的循环引用对象
Python 3的垃圾回收器能处理普通循环引用,但如果循环链中的对象定义了自定义__del__方法,GC无法确定安全的销毁顺序,会把这类对象放入“不可回收”集合,解释器退出时也不会调用它们的__del__。比如:class A: def __del__(self): print("A被销毁") class B: def __del__(self): print("B被销毁") a = A() b = B() a.b = b b.a = a运行后退出解释器,大概率看不到
__del__的打印输出。全局命名空间中的对象
解释器退出时会以不确定的顺序清理全局变量。如果某个全局对象依赖的资源已经被提前清理,或者全局引用链复杂,可能导致__del__无法正常执行,甚至直接被跳过。比如全局对象持有数据库连接,但数据库驱动已被先一步卸载。被C扩展或运行时内部引用的对象
某些C扩展模块创建的对象,可能被Python运行时的底层内部结构持有引用,这些引用不在GC的追踪范围内。解释器退出时不会遍历这类内部引用,自然不会调用对象的__del__。守护线程持有的对象
主线程退出时,守护线程会被强制终止,线程内持有的对象引用来不及被GC处理,__del__也就不会触发。示例:import threading import time class MyObj: def __del__(self): print("MyObj被销毁") def daemon_task(): global obj obj = MyObj() while True: time.sleep(1) threading.Thread(target=daemon_task, daemon=True).start() time.sleep(2)主线程结束后,守护线程立刻终止,
obj的__del__几乎不会执行。特殊引用类型的对象
比如通过ctypes绑定的外部系统资源、某些第三方库自定义的非追踪引用,这些对象的引用关系不被Python GC识别,解释器退出时无法自动触发__del__。解释器被强制终止时
如果用SIGKILL(Linux/macOS)、任务管理器强制结束进程这类方式终止Python,解释器没有机会执行任何清理逻辑,所有对象的__del__都不会被调用。
内容的提问来源于stack exchange,提问作者Alex Bochkarev

