[Python-ideas] breaking cycles that include __del__

Adam Olsen rhamph at gmail.com
Tue Oct 20 19:31:03 CEST 2009


On Tue, Oct 20, 2009 at 10:58, Daniel Stutzbach
<daniel at stutzbachenterprises.com> wrote:
> I'm playing around with this, and in following variant the weakref callback
> is never called (in Python 2.6 and 3.1).  I do not see why.  I know I've
> created a cycle between the callback and the object itself, but the garbage
> collector should detect and free the cycle.
>
> import weakref, gc
> class Foo:
>     def __init__(self):
>         self._weakref = weakref.ref(self, self.__free__)
>     def __free__(self):
>         print("I'm free!")
> x = Foo()
> del x
> gc.collect()
> print('test')
> print(gc.garbage)

Your weakref callback is a method of your object.  The callback
requires that method still be alive, but isn't triggered until self is
deleted.  If the GC does anything it'll have to include clearing the
weakref, deleting the callback.

Note that, for robustness, it's preferable to make the weakref
globally reachable until it's called, such as in a set.

Also note that Antoine's example saved a snapshot of the object's id.
Storing state is harder, and requires you to encapsulate it in some
other object.  A list for Antoine's 'r' argument might be a decently
simple bodge.


-- 
Adam Olsen, aka Rhamphoryncus



More information about the Python-ideas mailing list