Garbage collection
Nick Craig-Wood
nick at craig-wood.com
Tue Feb 19 07:30:03 EST 2008
Hrvoje Niksic <hniksic at xemacs.org> wrote:
> Simon Pickles <sipickles at googlemail.com> writes:
>
> > Ken wrote:
> >> What is your __del__ method doing?
> >>
> > Actually, nothing but printing a message when the object is deleted,
> > just morbid curiosity.
> >
> > I've yet to see one of the destructor messages, tho....
>
> Do your objects participate in reference cycles? In that case they
> are deallocated by the cycle collector, and the cycle collector
> doesn't invoke __del__.
>
> >>> class X(object):
> ... def __del__(self): print "gone"
> ...
> >>> a = X()
> >>> a = 1
> gone
> >>> b = X()
> >>> b.someslot = b
> >>> b = 1
> >>> import gc
> >>> gc.collect()
> 0
> >>>
If you want to avoid this particular problem, use a weakref.
>>> c = X()
>>> from weakref import proxy
>>> c.weak_reference = proxy(c)
>>> c.weak_reference.__del__
<bound method X.__del__ of <__main__.X object at 0xb7d1e56c>>
>>> c = 1
>>> gc.collect()
gone
0
>>>
Or perhaps slightly more realistically, here is an example of using a
WeakKeyDictionary instead of __del__ methods for keeping an accurate
track of all classes of a given type.
from weakref import WeakKeyDictionary
class Y(object):
_registry = WeakKeyDictionary()
def __init__(self):
self._registry[self] = True
@classmethod
def list(cls):
return cls._registry.keys()
a = Y()
b = Y()
c = Y()
Y.list()
a = 1
c = 1
Y.list()
Which produces the output
[<__main__.Y object at 0xb7d9fc8c>, <__main__.Y object at 0xb7d9fcac>, <__main__.Y object at 0xb7d9fc2c>]
[<__main__.Y object at 0xb7d9fc8c>]
(It behaves slightly differently in the interactive interpreter for
reasons I don't understand - so save it to a file and try it!)
In fact I find most of the times I wanted __del__ can be fixed by
using a weakref.WeakValueDictionary or weakref.WeakKeyDictionary for a
much better result.
--
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick
More information about the Python-list
mailing list