gpt4 book ai didi

python - Python 中的 RAII : What's the point of __del__?

转载 作者:太空狗 更新时间:2023-10-29 21:34:16 25 4
gpt4 key购买 nike

乍一看,Python 的 __del__ 特殊方法似乎提供了与 C++ 中的析构函数相同的优势。但是根据 Python 文档 (https://docs.python.org/3.4/reference/datamodel.html),不能保证您的对象的 __del__ 方法会被调用!

It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

所以也就是说,方法没用!不是吗?可能会或可能不会被调用的 Hook 函数实际上并没有多大用处,因此 __del__ 没有提供任何关于 RAII 的信息。如果我有一些必要的清理工作,我不需要它在某些时候运行,哦,当 GC 真正需要它时,我需要它可靠地、确定性地运行100% 的时间

我知道 Python 提供了上下文管理器,这对于该任务更有用,但为什么要保留 __del__ 呢?有什么意义?

最佳答案

__del__ 是终结器。它不是析构函数。终结器和析构器是完全不同的动物。

析构函数被可靠地调用,并且只存在于具有确定性内存管理的语言(例如 C++)中。 Python 的上下文管理器(with 语句)在某些情况下可以实现类似的效果。这些是可靠的,因为对象的生命周期是精确固定的;在 C++ 中,当对象被显式deleted 或退出某个作用域时(或者当智能指针响应自身的销毁而删除它们时),对象就会死亡。那就是析构函数运行的时候。

终结器调用不可靠。终结器的唯一有效用法是 an emergency safety net (注意:本文是从 .NET 的角度编写的,但概念翻译得相当好)。例如,open() 返回的文件对象在结束时自动关闭。但是你仍然应该自己关闭它们(例如使用 with 语句)。这是因为对象是由垃圾收集器动态销毁的,垃圾收集器可能会或可能不会立即运行,并且对于分代垃圾收集,它可能会或可能不会在任何给定的传递中收集某些对象。由于没有人知道我们将来会发明什么样的优化,因此最安全的假设是您无法知道垃圾收集器何时开始收集您的对象。这意味着您不能依赖终结器。

在 CPython 的特定情况下,由于使用了引用计数(这比垃圾收集更简单和更可预测),您可以获得稍微更强的保证。如果您可以确保您永远不会创建涉及给定对象的引用循环,那么该对象的终结器将在可预测的时间点(当最后一个引用死亡时)被调用。这适用于 CPython、引用实现,不是 PyPy、IronPython、Jython 或任何其他实现。

关于python - Python 中的 RAII : What's the point of __del__?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28300946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com