class Package:
def __init__(self):
self.files = []
# ...
def __del__(self):
for file in self.files:
os.unlink(file)
Run Code Online (Sandbox Code Playgroud)
__del__(self)上面因AttributeError异常而失败.我理解Python在__del__()调用时不保证存在"全局变量"(在此上下文中的成员数据?).如果是这种情况并且这是异常的原因,我该如何确保对象正确破坏?
在python 3中编写自定义__del__方法或依赖stdlib 1中的一个用例是什么?也就是说,在什么情况下它是相当安全的,并且可以做一些没有它的事情很难做到的事情?
出于很多好的理由(1 2 3 4 5 6),通常的建议是避免__del__使用上下文管理器或手动执行清理:
__del__如果对象在intrepreter出口2上处于活动状态,则不保证会被调用.gc暗示的不可预测性更不确定.__del____del__必须仔细编写:
__init__可能不存在,因为__init__可能引发了异常;stderr);更新:
PEP 442在行为上做出了重大改进__del__.虽然我的第1-4点仍然有效?
更新2:
一些顶级的python库包含__del__在后PEP 442 python(即python 3.4+)中的使用.我想我的观点3在PEP 442之后不再有效,其他点被接受为对象终结的不可避免的复杂性.
1我将问题从编写自定义__del__方法扩展到包括依赖于__del__stdlib.
2似乎__del__总是在更新版本的Cpython中调用解释器退出(有没有人有反例?).然而,对于__del__可用性的目的并不重要:文档明确地不提供对此行为的保证,因此不能依赖它(它可能在将来的版本中发生变化,在非CPython解释器中可能会有所不同) .
我正在研究一个实现上下文管理器的类似连接的对象。强烈鼓励写这样的东西:
with MyConnection() as con:
# do stuff
Run Code Online (Sandbox Code Playgroud)
当然也可以这样做:
con = MyConnection()
# do stuff
con.close()
Run Code Online (Sandbox Code Playgroud)
但未能关闭连接是相当有问题的。所以关闭__del__()似乎是一个好主意:
def __del__(self):
self.close()
Run Code Online (Sandbox Code Playgroud)
这看起来很不错,但有时会导致错误:
Exception ignored in: [...]
Traceback (most recent call last):
File "...", line xxx, in __del__()
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)
看起来好像有时 close 方法已经被销毁,当__del__()被调用时。
所以我正在寻找一种很好的方法来鼓励 python 在破坏时正确关闭连接。如果可能的话,我想,以避免代码重复close()和__del__()