乍一看,Python的__del__特殊方法似乎提供了析构函数在C++中具有的相同优势.但是根据Python文档(https://docs.python.org/3.4/reference/datamodel.html),无法保证您的对象的__del__方法完全被调用!
无法保证
__del__在解释器退出时仍然存在的对象调用()方法.
换句话说,这个方法没用!不是吗?可能会或可能不会被调用的钩子函数确实没有多大好处,因此__del__对RAII没有任何帮助.如果我有一些必要的清理,我不需要它运行一些时间,哦,当GC感觉它真的,我需要它可靠,确定和100%的时间运行.
我知道Python提供了上下文管理器,它对于该任务更有用,但为什么要__del__保持原样呢?重点是什么?
Kev*_*vin 10
__del__是终结者.它不是一个析构函数.终结者和破坏者是完全不同的动物.
可以可靠地调用析构函数,并且只存在具有确定性内存管理的语言(例如C++).Python的上下文管理器(with语句)在某些情况下可以实现类似的效果.这些是可靠的,因为物体的寿命是精确固定的; 在C++中,对象在显式deleted或者退出某个范围时(或者当智能指针为了响应自身的破坏而删除它们时)会死亡.这就是析构函数运行的时候.
终结器不能可靠地调用.终结器的唯一有效用途是作为紧急安全网(注意:本文是从.NET角度编写的,但概念转换得相当好).例如,返回的文件对象open()在完成时自动关闭.但你仍然应该自己关闭它们(例如使用with声明).这是因为垃圾收集器动态地销毁对象,垃圾收集器可能会立即运行,也可能不立即运行,并且通过分代垃圾收集,它可能会或可能不会收集任何给定传递中的某些对象.由于没有人知道我们将来可能会发明什么样的优化,因此最安全地假设您无法知道垃圾收集器何时会收集您的对象.这意味着你不能依赖终结者.
在CPython的特定情况下,由于使用引用计数(比垃圾收集更简单,更可预测),您可以得到更强的保证.如果您可以确保永远不会创建涉及给定对象的引用循环,则将在可预测的位置调用该对象的终结器(当最后一个引用死亡时).这是唯一的真正的CPython的,参考实现,而不是 PyPy,IronPython的,Jython的,或者任何其他的实现.