WeakrefValueDictionary of Callables?
Steve Holden
steve at holdenweb.com
Sun May 21 02:02:33 EDT 2006
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
More information about the Python-list
mailing list