哪些对象在 Python 解释器退出时不会被销毁?

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可以通过守护线程拥有的引用进行访问。


pig*_*mer 7

当解释器正常退出时,例如程序结束或被sys.exit调用,并不保证所有对象都会被销毁。这可能有一定的逻辑,但不是非常简单的逻辑。毕竟,该__del__方法是为了释放内存资源,而不是其他资源(如网络连接)——这就是__enter____exit__的用途。

话虽如此,有些情况__del__肯定不会被调用。与此平行的是atexit函数;它们通常在出口处运行。然而:

注意:当程序被 Python 未处理的信号杀死、检测到 Python 致命内部错误或调用时,不会调用通过此模块注册的函数os._exit()

atexit文档

因此,在某些情况下,不会调用注册的清理函数,例如__del____exit__和 函数:atexit

  1. 程序被 Python 未处理的信号杀死 - 如果程序收到停止信号,例如 SIGINT 或 SIGQUIT,并且它不处理该信号,那么它将被停止。

  2. 发生 Python 致命解释器错误。

  3. os._exit()被称为 - 文档说:

    以状态n退出进程,不调用清理处理程序、刷新 stdio 缓冲区等。

    所以很明显不__del__应该被调用。

综上所述,解释器不保证__del__被调用,但是有些情况是肯定不会被调用的。