为何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
相关产品推荐
相关产品推荐

