Deleting objects with method reference

Discussion in 'Python' started by Martin, Apr 14, 2004.

  1. Martin

    Martin Guest

    I can't delete this object after I call the Set() function.

    Why is this so special, and are there any way around it besides removing the ref ?

    class B:
    def __del__(self):
    print "del"
    def F(self):
    print "f"
    def Set(self):
    self.v = self.F


    o1 = B()
    o1.Set()
    del o1


    o2 = B()
    o2.Set()
    o2.v = None
    del o2
    >>> "del"



    -Martin
     
    Martin, Apr 14, 2004
    #1
    1. Advertising

  2. Martin

    Peter Otten Guest

    Martin wrote:

    > I can't delete this object after I call the Set() function.
    >
    > Why is this so special, and are there any way around it besides removing
    > the ref ?
    >
    > class B:
    > def __del__(self):
    > print "del"
    > def F(self):
    > print "f"
    > def Set(self):
    > self.v = self.F
    >
    >
    > o1 = B()
    > o1.Set()
    > del o1
    >
    >
    > o2 = B()
    > o2.Set()
    > o2.v = None
    > del o2
    >>>> "del"


    self.F consists of a function and an instance reference, so you are
    introducing a cycle with o1 referring self.F and self.F referring to o1.
    Cycles can only be garbage-collected if the objects involved do not have a
    __del__() method. In your example o1 would be collected if you weren't
    looking, i. e. B wouldn't attempt to trace the deletion with __del__().
    See http://www.python.org/doc/current/lib/module-gc.html, especially the
    "garbage" section for details.

    You can verify this with a weakref.ref object with an appropriate callback:

    import weakref
    def ondel(o):
    print "del"

    class B:
    def F(self):
    print "f"
    def Set(self):
    self.v = self.F


    o1 = B()
    o1.Set()
    w = weakref.ref(o1, ondel)
    del o1

    Peter
     
    Peter Otten, Apr 14, 2004
    #2
    1. Advertising

  3. Martin

    Martin Guest

    Peter Otten <> wrote in message news:<c5iusn$v32$03$-online.com>...
    > ...
    > You can verify this with a weakref.ref object with an appropriate callback:
    >
    > import weakref
    > def ondel(o):
    > print "del"
    >
    > class B:
    > def F(self):
    > print "f"
    > def Set(self):
    > self.v = self.F
    >
    >
    > o1 = B()
    > o1.Set()
    > w = weakref.ref(o1, ondel)
    > del o1
    >
    > Peter


    Hi Peter and thanks for your reply!

    However your example doesn't seem to work.

    import weakref
    import gc

    def ondel(o):
    print "del"

    class B:
    def F(self):
    print "f"
    def Set(self):
    self.v = self.F

    o1 = B()
    w1 = weakref.ref(o1, ondel)
    del o1
    >>> del


    o2 = B()
    o2.Set()
    w2 = weakref.ref(o2, ondel)
    del o2

    When I delete o2 I get no output. And gc.garbage is still empty!

    gc.garbage
    >>> []


    I have tried it in both python 2.1 and 2.3.3. Why doesn't it work?

    -Martin
     
    Martin, Apr 15, 2004
    #3
  4. Martin

    Jeff Epler Guest

    It works here when I call gc.collect(). There's not exactly a guarantee
    about when garbage will be collected otherwise.
    >>> o2 = B()
    >>> o2.Set()
    >>> w2 = weakref.ref(o2, ondel)
    >>> del o2
    >>> gc.collect()

    del
    3

    Jeff
     
    Jeff Epler, Apr 15, 2004
    #4
  5. Martin

    Peter Otten Guest

    Martin wrote:

    > However your example doesn't seem to work.
    >
    > import weakref
    > import gc
    >
    > def ondel(o):
    > print "del"
    >
    > class B:
    > def F(self):
    > print "f"
    > def Set(self):
    > self.v = self.F
    >
    > o1 = B()
    > w1 = weakref.ref(o1, ondel)
    > del o1
    >>>> del

    >
    > o2 = B()
    > o2.Set()
    > w2 = weakref.ref(o2, ondel)
    > del o2
    >
    > When I delete o2 I get no output. And gc.garbage is still empty!
    >
    > gc.garbage
    >>>> []

    >
    > I have tried it in both python 2.1 and 2.3.3. Why doesn't it work?


    I've cut and pasted the above, put it into ondel.py,
    removed
    >>> del

    added
    print gc.garbage
    as the last line and executed it (on Linux). Here's what I got:

    $ python2.1 ondel.py
    del
    []
    $ python2.2 ondel.py
    del
    []
    $ python2.3 ondel.py
    del
    []
    del
    $

    So at least with python 2.3.3 ondel() is called for both objects. The order
    however suggests interference with the shutdown process. Adding
    gc.collect()
    before
    print gc.garbage
    this changes to

    $ python2.3 ondel.py
    del
    del
    []
    $ python2.2 ondel.py
    del
    del
    []
    $ python2.1 ondel.py
    del
    del
    []

    which I would have expected in the first place. So why does(n't) it work
    that way? I have no idea, but explicitly invoking the garbage collector
    does definitely not seem the way to go.

    Peter
     
    Peter Otten, Apr 15, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jimjim
    Replies:
    0
    Views:
    368
    jimjim
    Feb 27, 2004
  2. Harry Barker
    Replies:
    2
    Views:
    521
    Alf P. Steinbach
    Apr 19, 2006
  3. 7stud
    Replies:
    11
    Views:
    700
    Dennis Lee Bieber
    Mar 20, 2007
  4. Steve Drach
    Replies:
    3
    Views:
    212
    Thomas E Enebo
    Jun 20, 2004
  5. crea
    Replies:
    2
    Views:
    417
    Nobody
    Dec 28, 2012
Loading...

Share This Page