Ale*_*lex 15 python garbage-collection
根据Python文档:
不保证为
__del__()解释器退出时仍然存在的对象调用方法。
我知道在旧版本的 Python 中,循环引用将是这种行为的示例之一,但是据我了解,在 Python 3 中,此类循环将在解释器退出时成功销毁。
我想知道解释器在退出时不会销毁对象的情况是什么(尽可能接近详尽的列表)。
use*_*ica 11
所有示例都是实现细节 - Python 不承诺它是否会__del__在解释器退出时调用任何特定对象。也就是说,最简单的示例之一是守护线程:
import threading
import time
def target():
time.sleep(1000)
class HasADel:
def __del__(self):
print('del')
x = HasADel()
threading.Thread(target=target, daemon=True).start()
Run Code Online (Sandbox Code Playgroud)
在这里,守护线程防止HasADel实例在解释器关闭时被垃圾收集。守护线程实际上并不对该对象执行任何操作,但 Python 无法清理守护线程拥有的引用,并且x可以通过守护线程拥有的引用进行访问。
当解释器正常退出时,例如程序结束或被sys.exit调用,并不保证所有对象都会被销毁。这可能有一定的逻辑,但不是非常简单的逻辑。毕竟,该__del__方法是为了释放内存资源,而不是其他资源(如网络连接)——这就是__enter__和__exit__的用途。
话虽如此,有些情况__del__肯定不会被调用。与此平行的是atexit函数;它们通常在出口处运行。然而:
注意:当程序被 Python 未处理的信号杀死、检测到 Python 致命内部错误或调用时,不会调用通过此模块注册的函数
os._exit()。
因此,在某些情况下,不会调用注册的清理函数,例如__del__、__exit__和 函数:atexit
程序被 Python 未处理的信号杀死 - 如果程序收到停止信号,例如 SIGINT 或 SIGQUIT,并且它不处理该信号,那么它将被停止。
发生 Python 致命解释器错误。
os._exit()被称为 - 文档说:
以状态n退出进程,不调用清理处理程序、刷新 stdio 缓冲区等。
所以很明显不__del__应该被调用。
综上所述,解释器不保证__del__被调用,但是有些情况是肯定不会被调用的。