You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python中__del__方法未被调用两次?

为什么__del__方法没有被调用两次?

我希望利用对象的__del__方法,根据特定条件自动将对象数据写入外部数据库或本地缓存(全局字典),但上下文管理器并不适用我的场景。

不过这意味着,当__del__因对象超出作用域被调用时,可能会在本地缓存中创建该对象的新引用。由于这看起来存在潜在问题,我编写了一个简单的测试用例:

cache = []

class Temp:
    def __init__(self) -> None:
        self.cache = True

    def __del__(self) -> None:
        print('Running del')
        if self.cache:
            cache.append(self)

def main():
    temp = Temp()
    print(temp.cache)

main()
if cache:
    print(cache[0].cache)

运行这段代码后,输出为:

True
Running del
True

而我预期的输出是:

True
Running del
True
Running del

即__del__会被调用两次:一次是在main函数结束时对象首次超出作用域,另一次是在程序结束时,因为缓存中存储了该对象的新引用。请问为何__del__没有被调用两次?


问题原因及解释

这是因为Python的垃圾回收机制对带有__del__方法的对象有特殊处理逻辑:

  • 引用复活导致__del__仅执行一次:当main函数结束后,temp引用失效,垃圾回收器触发__del__方法。但你在__del__里把对象添加到全局cache列表,给对象新增了有效引用——也就是所谓的引用复活。Python明确规定,无论对象被复活多少次,它的__del__方法只会被调用一次,后续即使该对象的所有引用再次失效,也不会再触发__del__。

  • 程序退出时的简化清理:当Python程序即将退出时,会直接清理剩余对象,不会严格执行常规的垃圾回收流程。对于已经调用过__del__的对象,系统不会重复调用其__del__方法。

如果要实现自动写入缓存/数据库的需求,不建议依赖__del__的复活逻辑,最好显式管理对象生命周期,或者改用弱引用配合定时检查这类更可靠的方案。

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:37:18