我看到一些代码在对象上显式调用了__del__
,这让我感到好奇,所以我试着玩一下来理解它的工作原理。
我尝试了以下代码(我知道仅仅使用__del__
本身可能是不好的,但我只是想自学一下):
class A:
def __init__(self, b):
self.a = 123
self.b = b
print "a is {}".format(self.a)
def __del__(self):
self.a = -1
print "a is {}".format(self.a)
self.b.dont_gc_me = self
def foo(self):
self.a = 9999999
print "a is {}".format(self.a)
class Foo:
def __init__(self):
self.a = 800
def __del__(self):
self.a = 0
然后我在IPython控制台中尝试了以下操作:
In [92]: f = Foo()
In [93]: a = A(f)
a is 123
In [94]: a = None
a is -1
In [95]: f.__dict__
Out[95]: {'a': 800, 'dont_gc_me': <__main__.A instance at 0x2456830>}
In [96]: f = None
In [97]:
我发现,即使实例a的引用由Foo的实例f保持,__del__方法也只被调用一次;当我将后者设置为None时,我没有看到析构函数第二次被调用。
Python文档中提到:
注意,__del__() 方法可以通过创建对实例的新引用来延迟实例的销毁(虽然不建议这样做!)。在删除此新引用时,可能会在以后的某个时间调用它。不能保证在解释器退出时仍存在的对象会调用__del__()方法。
这似乎意味着__del__方法可能会被再次调用,但并不保证。那么我的问题是:是否存在某种情况,__del__会被再次调用?(我认为上面将f设置为None会这样做,但事实并非如此)。还有其他值得注意的细节吗?