She*_*evy 14 python destructor
从python文档:
无法保证
__del__()在解释器退出时仍然存在的对象调用方法.
为什么不?如果做出这种保证会出现什么问题?
我不相信以前的答案.
首先请注意,给出的示例不会阻止__del__在退出期间调用方法.事实上,当前的CPythons 将调用__del__给定的方法,在Python 2.7的情况下调用两次,在Python 3.4的情况下调用一次.所以这不能成为"杀手级的例子",它说明了为什么不做出保证.
我认为文档中的陈述不是出于设计原则的动机,即调用析构函数会很糟糕.尤其是因为似乎在CPython 3.4及更高版本中它们总是按照您的预期被调用,这个警告似乎没有实际意义.
相反,我认为该语句只是反映了这样一个事实:CPython实现有时并没有在退出时调用所有析构函数(大概是为了便于实现).
情况似乎是CPython 3.4和3.5总是在解释器退出时调用所有析构函数.
相比之下,CPython 2.7并不总能做到这一点.当然__del__,通常不会在具有循环引用的对象上调用方法,因为如果这些对象具有__del__方法,则无法删除这些对象.垃圾收集器不会收集它们.当解释器退出时,对象确实消失了(当然)它们没有最终确定,因此它们的__del__方法永远不会被调用.在实施PEP 442之后,Python 3.4中不再适用.
但是,似乎Python 2.7也没有最终确定具有循环引用的对象,即使它们没有析构函数,如果它们只在解释器出口期间变得无法访问.
据推测,这种行为是特别的,很难解释它最好只是通过一般免责声明表达 - 正如文档所做的那样.
这是一个例子:
class Foo(object):
def __init__(self):
print("Foo init running")
def __del__(self):
print("Destructor Foo")
class Bar(object):
def __init__(self):
print("Bar1 init running")
self.bar = self
self.foo = Foo()
b = Bar()
# del b
Run Code Online (Sandbox Code Playgroud)
随着del b注释掉,在析构函数Foo是不是在Python 2.7叫虽然它是在Python 3.4.
随着del b增加,析构函数是在两种情况下调用(在解释退出).
如果你做了一些令人讨厌的事情,你可能会发现自己有一个不可删除的对象,python 会尝试永远删除该对象:
class Phoenix(object):
def __del__(self):
print "Deleting an Oops"
global a
a = self
a = Phoenix()
Run Code Online (Sandbox Code Playgroud)
__del__无论如何,依赖都不是很好,因为 python 不保证何时删除对象(尤其是具有循环引用的对象)。也就是说,也许将您的类变成上下文管理器是一个更好的解决方案...然后您可以保证即使在发生异常等情况下也会调用清理代码...
| 归档时间: |
|
| 查看次数: |
3476 次 |
| 最近记录: |