在Python 3中,编写自定义__del__
方法或依赖于stdlib中的1之一,有哪些用例?也就是说,在什么情况下使用它是相当安全的,并且可以做一些难以在没有它的情况下完成的事情?
出于许多很好的原因(123456),通常的建议是避免使用__del__
而是使用上下文管理器或手动清理:
- 如果对象在解释器退出时仍存活,那么不能保证会调用
__del__
2。 - 当一个对象可以被销毁的时候,引用计数实际上可能是非零的(例如,引用可能通过由调用函数持有的回溯帧幸存下来)。这使得销毁时间比
gc
的简单不可预测性更加不确定。 - 如果循环包括多个具有
__del__
的对象,则垃圾回收器无法清除它们 __del__
内部的代码必须非常小心地编写:- 因为
__init__
可能会引发异常,所以在__init__
中设置的对象属性可能不存在; - 异常被忽略(只打印到
stderr
) - 全局变量可能不再可用。
- 因为
更新:
PEP 442 对 __del__
的行为进行了显著改进。不过似乎我的1-4观点仍然成立?
更新2:
一些顶级Python库采用了在后-PEP 442 python(即python 3.4+)中使用__del__
的方式。我想PEP 442之后我的第3个观点已不再成立,而其他观点则被接受为对象终止复杂性不可避免。
1我将问题从编写自定义__del__
方法扩展到包括依赖于stdlib的__del__
。
2似乎在较新版本的Cpython中总是在解释器退出时调用__del__
(有没有反例?)。但是,对于__del__
的可用性来说并不重要:文档明确地没有提供关于此行为的任何保证,因此不能依赖它(它可能在未来版本中发生变化,在非CPython解释器中可能不同)。
__del__
,并且我计划完全放弃它。在我这样做之前,我想确保我没有错过任何不应该避免它的情况。由于我(以及大多数SO上的人)不贡献于stdlib,我希望通过排除它来简化问题。 - max__del__
。您必须足够关心清理才会费心编写__del__
。但是,如果清理偶尔从未发生或比预期晚得多(因为这是__del__
的语义),您并不介意。什么样的清理工作适合呢?也许是释放内存,但这已经由垃圾回收处理了。也许可以帮助垃圾回收器在内存不足时释放内存? - max__del__
调用,大多数Python实现在内存变得“稀疏”时收集对象。因此,您不关心“立即清理”,而只关心“最终清理”。 - MSeifert