为什么 __del__ 不被调用两次?

问题描述 投票:0回答:1

我想使用对象的

__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 destructor
1个回答
0
投票

这是特定于实现的行为,请参阅

__del__
的文档。您正在执行“复活”,即中止对象的垃圾收集。然而,在旧版本的 python 中,这很容易使你的解释器崩溃,因为 PEP 442 这应该大部分工作。然而,CPython 特别不会在解释器关闭时调用复活对象的
__del__

一般来说,避免在

__del__
方法中访问不直接与对象关联的任何内容,包括全局
cache
变量。无法保证它仍然存在。

对于此用例,请使用上下文管理器,或者因为这些显然对您不可用,

atexit

© www.soinside.com 2019 - 2024. All rights reserved.