I have a strange problem while trying to delete the last reference of an object.
The code is:
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]()))
And the output is this:
reference count before killed: 2
'a' is dead.
reference count after killed: 1547
'd' is dead.
'c' is dead.
But sometimes (it is totally random) I got only 'd' is dead.
or 'c' is dead.
(but never 'b' is dead.
), or none of these messages at all.
So my first question is: What is this weird reference count 1547
? And where does it come from?
And the second is: Why killing instance a
creates this random "killing other instances" effect?
After a
is GC'd, d.ref[0]()
produces None
. That's why you're getting a refcount of 1547 after deleting a
; after all, you couldn't ask for the refcount of a collected object, could you?
The weird deletion of c
and d
is because Python doesn't guarantee whether objects alive when the interpreter exits will go through the normal destruction process. b
, c
, and d
are all alive at the end of your script. Sometimes, they'll get GC'd normally, and the weakref callbacks will run. Sometimes, that doesn't happen. Python makes no promises here.