Lloyd Weehuizen wrote: > Hey > > 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? > > Example: > 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: import weakref TEST_EVENT = 1 class TestBinder: def __init__(self): self.entries = weakref.WeakValueDictionary() def BindFunction(self, event_id, obj): self.entries[event_id] = obj def CallFunction(self, event_id, *args): self.entries[event_id].TestFunction(*args) class TestCase: def __init__(self, binder): binder.BindFunction(TEST_EVENT, self) def TestFunction(self): print "TestFunction OK" test_binder = TestBinder() test_case = TestCase(test_binder) test_binder.CallFunction(TEST_EVENT) 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 parent object. 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. regards Steve -- 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 -- http://mail.python.org/mailman/listinfo/python-list