It is __del__ calling twice for some instances?
Duncan Booth
duncan.booth at invalid.invalid
Fri Aug 18 03:50:56 EDT 2006
Max Yuzhakov wrote:
> Why for some instance __del__ called twice?
> Such behaviour of __del__ seems to me unpredictable.
Here's a slightly modified version of your code. The 51st object destroyed
gets its __del__ method called twice. It doesn't matter how long your loop
is, every 50th object gets special treatment (or perhaps it is the 49th).
The good news is that there is a way to stop it happening: just add an
explicit "del self.other" at the end of __del__. The bad news is that if
your list is too long that will cause a flood of error messages and won't
call the destructors at all past the first 1000.
As to why it happens, there is a mechanism in Python to stop unlimited
stack being used when objects are freed: when the stack gets too deep then
instead of being released, the Py_DECREF call puts the object into a
trashcan list and the objects aren't released until the stack has unwound.
It looks like there must be a bug round the trashcan mechanism somewhere.
BTW, the behaviour is completely different if you use a new style class,
but still somewhat bizarre: for new style classes only the first 25 objects
get freed when you clear a, the remainder are only released by the garbage
collector.
#!/usr/local/bin/python -d
# -*- coding: koi8-u -*-
class foo:
def __init__(self, other):
self.other = other
self._deleted = False
global ini_cnt
ini_cnt +=1
def __del__(self):
if self._deleted:
print "aargh!"
self._deleted = True
global del_cnt
del_cnt +=1
print "del",del_cnt,"at",id(self)
def stat():
print "-"*20
print "ini_cnt = %d" % ini_cnt
print "del_cnt = %d" % del_cnt
print "difference = %d" % (ini_cnt-del_cnt)
ini_cnt = 0
del_cnt = 0
loop_cnt = 54
a = foo(None)
for i in xrange(loop_cnt):
a = foo(a)
stat()
a = None
stat()
More information about the Python-list
mailing list