我在尝试删除对象的最后一个引用时遇到了一个奇怪的问题。
代码为:
import sys
import weakref
class Ref:
def __init__(self, name):
self.name = name
self.ref = []
def reference(self, obj):
name = obj.name
self.ref.append(
weakref.ref(obj, lambda wref: print('{!r} is dead.'.format(name))))
a = Ref('a')
b = Ref('b')
c = Ref('c')
d = Ref('d')
a.reference(b)
b.reference(c)
c.reference(d)
d.reference(a)
print('reference count before killed:', sys.getrefcount(d.ref[0]()))
del a
print('reference count after killed:', sys.getrefcount(d.ref[0]()))
输出是这样的:
reference count before killed: 2
'a' is dead.
reference count after killed: 1547
'd' is dead.
'c' is dead.
但有时(完全随机)我只收到'd' is dead.
或'c' is dead.
(但从未收到'b' is dead.
),或者根本没有这些消息。
所以我的第一个问题是:这个奇怪的参考计数1547
是什么?它从何而来?
第二个问题是:为什么杀死实例a
会产生这种随机的"杀死其他实例"的效果?
a
被 GC'd 后,d.ref[0]()
产生None
。这就是为什么您在删除 1547 后得到 a
的引用计数;毕竟,您不能要求收集对象的参考计数,对吗?
奇怪的删除c
和d
是因为Python不能保证解释器退出时处于活动状态的对象是否会经历正常的销毁过程。 b
、c
和d
在剧本结束时都还活着。有时,它们会正常获得 GC'd,并且弱引用回调将运行。有时,这不会发生。Python在这里不做任何承诺。