Nick Craig-Wood <[EMAIL PROTECTED]> wrote: > [<__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!)
Any expression in the interactive interpreter is implicitly assigned to the variable '_', so after your first call to Y.list() you've saved references to the complete list in _. Assignments aren't expressions so after assigning to a and c you haven't changed _. If you throw in another unrelated expression you'll be fine: >>> a = Y() >>> b = Y() >>> c = Y() >>> Y.list() [<__main__.Y object at 0x0117F230>, <__main__.Y object at 0x0117F2B0>, <__main__.Y object at 0x0117F210>, <__main__.Y object at 0x0117F670>, <__main__.Y object at 0x0117F690>, <__main__.Y object at 0x0117F6B0>, <__main__.Y object at 0x0117F310>] >>> a = 1 >>> c = 1 >>> c 1 >>> Y.list() [<__main__.Y object at 0x0117F6B0>] > 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. The WeakValueDictionary is especially good when you want a Python wrapper round some external non-python thing, just use the address of the external thing as the key for the dictionary and you can avoid having duplicate Python objects. The other option for classes involved in a cycle is to move the __del__ (and anything it needs) down to another class which isn't part of the cycle, so the original example becomes: >>> class Monitor(object): def __del__(self): print "gone" >>> class X(object): def __init__(self): self._mon = Monitor() >>> a = X() >>> a = 1 gone >>> b = X() >>> b.someslot = b >>> b = 1 >>> import gc >>> gc.collect() gone 8 >>> -- http://mail.python.org/mailman/listinfo/python-list