Strange behavior of weak references (weakref module)

Jason Orendorff jason at jorendorff.com
Thu Dec 20 00:10:24 CET 2001


> I found this behavior (bug?) when I want to create weak reference to a
> instance method. It's hard to describe (using my poor English writing
> ability), so I just attach the way to reproduce the situation. And
> notice that the id() of a instance method reference changes after each
> function call!

This is correct behavior.  Each time you do a.test, Python creates
a new "bound instance method" object.

>>> class A:
...     def foo(self, word):
...         print "foo:", word
...
>>> a = A()
>>> m = a.foo
>>> m.im_self
<__main__.A instance at 0x00948648>
>>> m.im_func
<function foo at 0x0092FD00>
>>>

You can create a "weak method reference" type that makes weak
references to both the object and the function.

import weakref

class WeakMethod:
    def __init__(self, method):
        self.self_ref = weakref.ref(method.im_self)
        self.func_ref = weakref.ref(method.im_func)
    def __call__(self, *args, **kwds):
        im_self = self.self_ref()
        im_func = self.func_ref()
        if im_self is None or im_func is None:
            # One or both of the references died.  Do nothing.
            return
        else:
            args = (im_self,) + args
            return im_func(*args, **kwds)

For example...

>>> a = A()
>>> z = WeakMethod(a.foo)
>>> z("spam")
foo: spam
>>> del a  # Get rid of a
>>> z("eggs")  # Does nothing, because the instance a is gone.
>>>

## Jason Orendorff    http://www.jorendorff.com/




More information about the Python-list mailing list