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() -- http://mail.python.org/mailman/listinfo/python-list