Hrvoje Niksic <[EMAIL PROTECTED]> wrote:
> Simon Pickles <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> -- http://www.craig-wood.com/nick
--
http://mail.python.org/mailman/listinfo/python-list