The untimely dimise of a weak-reference

  • Thread starter Vincent van Beveren
  • Start date
V

Vincent van Beveren

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: (e-mail address removed)
 
P

Peter Otten

Vincent said:
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
 
V

Vincent van Beveren

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:[email protected]]
Sent: vrijdag 30 juli 2010 15:06
To: (e-mail address removed)
Subject: Re: The untimely dimise of a weak-reference
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
 
P

Peter Otten

Vincent said:
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
 
G

Gregory Ewing

Vincent said:
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()
 
V

Vincent van Beveren

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
 
B

Bruno Desthuilliers

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)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top