The untimely dimise of a weak-reference

Discussion in 'Python' started by Vincent van Beveren, Jul 30, 2010.

  1. Hi everyone,

    I was working with weak references in Python, and noticed that it was impossible to create a weak-reference of bound methods. Here is a little python 3.0 program to prove my point:

    import weakref

    print("Creating object...")
    class A(object):

    def b(self):
    print("I am still here")

    a = A()

    def d(r):
    print("Aaah! Weakref lost ref")

    print("Creating weak reference")

    r = weakref.ref(a.b, d)

    print("Oh, wait, its already gone!")
    print("Ref == None, cause of untimely demise: %s" % r())
    print("Object is still alive: %s" % a)
    print("Function is still exists: %s" % a.b)
    print("See:")
    a.b()

    I also tried this in Python 2.5 and 2.6 (with minor modifications to the syntax of course), and it yielded the exact same behavior. Why is this, and is there anything I can do about it? I wish to reference these bound functions, but I do not want to keep them in memory once the object they belong to is no longer referenced.

    Regards,
    Vincent van Beveren

    ___
    Ing. V. van Beveren
    Software Engineer, FOM Rijnhuizen
    E:
     
    Vincent van Beveren, Jul 30, 2010
    #1
    1. Advertising

  2. Vincent van Beveren

    Peter Otten Guest

    Vincent van Beveren wrote:

    > Hi everyone,
    >
    > I was working with weak references in Python, and noticed that it was
    > impossible to create a weak-reference of bound methods. Here is a little
    > python 3.0 program to prove my point:
    >
    > import weakref
    >
    > print("Creating object...")
    > class A(object):
    >
    > def b(self):
    > print("I am still here")
    >
    > a = A()
    >
    > def d(r):
    > print("Aaah! Weakref lost ref")
    >
    > print("Creating weak reference")
    >
    > r = weakref.ref(a.b, d)


    The instance doesn't keep a reference of its bound method. Rather the bound
    method keeps a reference of its instance. Every time you say

    a.b

    you get a different bound method. What do you think should keep it alive?


    > print("Oh, wait, its already gone!")
    > print("Ref == None, cause of untimely demise: %s" % r())
    > print("Object is still alive: %s" % a)
    > print("Function is still exists: %s" % a.b)
    > print("See:")
    > a.b()
    >
    > I also tried this in Python 2.5 and 2.6 (with minor modifications to the
    > syntax of course), and it yielded the exact same behavior. Why is this,
    > and is there anything I can do about it? I wish to reference these bound
    > functions, but I do not want to keep them in memory once the object they
    > belong to is no longer referenced.


    I fear you have to manage the methods' lifetime explicitly.

    Peter
     
    Peter Otten, Jul 30, 2010
    #2
    1. Advertising

  3. Hi Peter,

    I did not know the object did not keep track of its bound methods. What advantage is there in creating a new bound method object each time its referenced? It seems kind of expensive.

    Regards,
    Vincent

    -----Original Message-----
    From: Peter Otten [mailto:]
    Sent: vrijdag 30 juli 2010 15:06
    To:
    Subject: Re: The untimely dimise of a weak-reference

    Vincent van Beveren wrote:

    > Hi everyone,
    >
    > I was working with weak references in Python, and noticed that it was
    > impossible to create a weak-reference of bound methods. Here is a little
    > python 3.0 program to prove my point:
    >
    > import weakref
    >
    > print("Creating object...")
    > class A(object):
    >
    > def b(self):
    > print("I am still here")
    >
    > a = A()
    >
    > def d(r):
    > print("Aaah! Weakref lost ref")
    >
    > print("Creating weak reference")
    >
    > r = weakref.ref(a.b, d)


    The instance doesn't keep a reference of its bound method. Rather the bound
    method keeps a reference of its instance. Every time you say

    a.b

    you get a different bound method. What do you think should keep it alive?


    > print("Oh, wait, its already gone!")
    > print("Ref == None, cause of untimely demise: %s" % r())
    > print("Object is still alive: %s" % a)
    > print("Function is still exists: %s" % a.b)
    > print("See:")
    > a.b()
    >
    > I also tried this in Python 2.5 and 2.6 (with minor modifications to the
    > syntax of course), and it yielded the exact same behavior. Why is this,
    > and is there anything I can do about it? I wish to reference these bound
    > functions, but I do not want to keep them in memory once the object they
    > belong to is no longer referenced.


    I fear you have to manage the methods' lifetime explicitly.

    Peter
     
    Vincent van Beveren, Jul 30, 2010
    #3
  4. Vincent van Beveren

    Peter Otten Guest

    Vincent van Beveren wrote:

    > I did not know the object did not keep track of its bound methods. What
    > advantage is there in creating a new bound method object each time its
    > referenced? It seems kind of expensive.


    While I didn't measure it I suppose that it saves a lot of memory.

    Peter
     
    Peter Otten, Jul 30, 2010
    #4
  5. Vincent van Beveren wrote:

    > I was working with weak references in Python, and noticed that it
    > was impossible to create a weak-reference of bound methods.


    > is there anything I can do about it?


    You can create your own wrapper that keeps a weak reference to
    the underlying object. Here's an example.

    import weakref

    class weakmethod(object):

    def __init__(self, bm):
    self.ref = weakref.ref(bm.im_self)
    self.func = bm.im_func

    def __call__(self, *args, **kwds):
    obj = self.ref()
    if obj is None:
    raise ValueError("Calling dead weak method")
    self.func(obj, *args, **kwds)

    if __name__ == "__main__":

    class A(object):

    def foo(self):
    print "foo method called on", self

    a = A()
    m = weakmethod(a.foo)
    m()
    del a
    m()
     
    Gregory Ewing, Jul 31, 2010
    #5
  6. Hi Gregory,


    > You can create your own wrapper that keeps a weak reference to
    > the underlying object. Here's an example.
    > [...]


    Thanks for the code!

    Regards,
    Vincent
     
    Vincent van Beveren, Aug 2, 2010
    #6
  7. Gregory Ewing a écrit :
    (snip)

    > import weakref
    >
    > class weakmethod(object):
    >
    > def __init__(self, bm):
    > self.ref = weakref.ref(bm.im_self)
    > self.func = bm.im_func
    >
    > def __call__(self, *args, **kwds):
    > obj = self.ref()
    > if obj is None:
    > raise ValueError("Calling dead weak method")
    > self.func(obj, *args, **kwds)


    Would be better with :

    return self.func(obj, *args, *kwds)
     
    Bruno Desthuilliers, Aug 2, 2010
    #7
  8. Bruno Desthuilliers wrote:

    > Would be better with :
    >
    > return self.func(obj, *args, *kwds)


    Thanks -- well spotted!

    --
    Greg
     
    Gregory Ewing, Aug 4, 2010
    #8
    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. Kuan Zhou
    Replies:
    1
    Views:
    5,198
    Paul Uiterlinden
    Jan 24, 2005
  2. Josef Garvi
    Replies:
    1
    Views:
    666
    Josef Garvi
    May 27, 2004
  3. Paul Pogonyshev

    weak reference callback

    Paul Pogonyshev, Aug 29, 2009, in forum: Python
    Replies:
    1
    Views:
    370
    larudwer
    Aug 30, 2009
  4. Ole Streicher

    weak reference to bound method

    Ole Streicher, Oct 2, 2009, in forum: Python
    Replies:
    15
    Views:
    656
    ryles
    Oct 3, 2009
  5. Charles Oliver Nutter
    Replies:
    0
    Views:
    106
    Charles Oliver Nutter
    Mar 12, 2010
Loading...

Share This Page