WeakrefValueDictionary of Callables?
steve at holdenweb.com
Sun May 21 08:02:33 CEST 2006
Lloyd Weehuizen wrote:
> I'm trying to set up a WeakrefValueDictionary of callables however as
> soon as my method that adds the callable to the dictionary exits the
> value is removed? Is there any way around this?
> import weakref
> TEST_EVENT = 1
> class TestBinder:
> def __init__( self ):
> self.entries = weakref.WeakValueDictionary()
> def BindFunction( self, event_id, function ):
> self.entries[event_id] = function
> def CallFunction( self, event_id, *args ):
> self.entries[event_id]( *args )
> class TestCase:
> def __init__( self, binder ):
> binder.BindFunction( TEST_EVENT, self.TestFunction )
> def TestFunction():
> print "TestFunction OK"
> test_binder = TestBinder()
> test_case = TestCase( test_binder )
> test_binder.CallFunction( TEST_EVENT )
> This generates a KeyError: 1, if I don't use weakrefs, then the TestCase
> object is never cleaned up until TestBinder is destroyed.
I believe your problem is that the bound method references aren't being
retained (i.e. referenced) anywhere else. A bound method is an object in
its own right, and can cease to exist at any time - particularly in your
case when the weak reference is the only reference to it!
Consider that the following code actually appears to work:
TEST_EVENT = 1
self.entries = weakref.WeakValueDictionary()
def BindFunction(self, event_id, obj):
self.entries[event_id] = obj
def CallFunction(self, event_id, *args):
def __init__(self, binder):
print "TestFunction OK"
test_binder = TestBinder()
test_case = TestCase(test_binder)
The difference is that now a reference to the object rather than its
bound method is stored, and your program *does* contain other references
to the TesTcase object. It's perfectly leagal to store weak references
to bound methods, but as you have seen they aren't referenced by their
Further notes: I have cleaned your code up to be closer to PEP 8
conformance (if you don't know what PEP 8 is you shoudl find out), and I
added the necessary "self" argument to the TestCase.TestFunction() method.
Hope this helps.
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Love me, love my blog http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden
More information about the Python-list