Parent references: hot or not?

Jp Calderone exarkun at intarweb.us
Sat Apr 19 12:59:23 EDT 2003


On Sat, Apr 19, 2003 at 10:07:41AM -0700, Dylan Reinhardt wrote:
> On Sat, 2003-04-19 at 10:00, Dylan Reinhardt wrote:
> 
> > Sounds like I should be sure to write a __del__ method for Container
> > that ensures things work correctly.
> 
> And upon re-reading your post you say *not* to do that... :-)
> 

  Glad you noticed that ;)

> I'd like to understand that a bit better.  What would be wrong with:
> 
> class Container:
> 
>    def __del__(self):
>       # ensure all Items are deleted first
>       for item in self.items.keys():
>          del self.items[item]
> 

    >>> import gc
    >>> gc.set_debug(1)
    >>> class Foo:
    ...     pass
    ...
    >>> a, b = Foo(), Foo()
    >>> a.b, b.a = b, a
    >>> del a, b
    >>> gc.collect()
    gc: collecting generation 2...
    gc: objects in each generation: 0 0 1215
    gc: done, 4 unreachable, 0 uncollectable.
              ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^

  Now, with __del__:

    >>> class Foo:
    ...     def __del__(self):
    ...         print 'Foo.__del__'
    ...
    >>> a, b = Foo(), Foo()
    >>> a.b, b.a = b, a
    >>> del a, b
    >>> gc.collect()
    gc: collecting generation 2...
    gc: objects in each generation: 0 0 1217
    gc: done, 4 unreachable, 4 uncollectable.
              ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^
    >>> gc.garbage
    [<__main__.Foo instance at 0x81b9d6c>, <__main__.Foo instance at 0x81b9d94>]


  As you can see, __del__ is never called, and a and b still exist as
members of the gc.garbage list.  There are some good reasons behind this,
but they are beyond the scope of this post ;)  If you pick up any good
reference on garbage collection, this should be covered.

  What it is possible to do, if you are very careful about it, is to examine
the objects in gc.garbage, break their cycles, remove them from gc.garbage,
then call gc.collect() again.  Since they are no longer in reference cycles,
they can be finalized and destroyed normally.

  I'm not sure if I've answered your original question.  Without more
details, I'm not sure what else to say but this: if you don't want things to
be collected and finalized, don't delete your references to them; if you do
want them to be collected (and maybe finalized), don't put them in cycles,
or don't implement __del__.  Or, go to the trouble described in the above
paragraph.

  Hope this helps,

  Jp

-- 
Seduced, shaggy Samson snored.
She scissored short.  Sorely shorn,
Soon shackled slave, Samson sighed,
Silently scheming,
Sightlessly seeking
Some savage, spectacular suicide.
                -- Stanislaw Lem, "Cyberiad"
-- 
 up 30 days, 13:02, 4 users, load average: 0.29, 0.22, 0.16





More information about the Python-list mailing list