Possible Duplicate:
Why doesn't the weakref work on this bound method?
A bit of context:
I was trying to implement an Listener (or Observer, same thing) pattern: An EventManager keeps a list of all the Listeners handlers interested in an Event. For example, a Listener object would have a onEndOfTheWorldEvent
method which would be called by the EventManager each time an instance of the event class EndOfTheWorldEvent is posted. Easy.
Except that I wanted to weak reference the handlers because I don't want the EventManager to keep my handlers (bound methods) alive when the Listener was not needed anymore.
So I thought "Let's throw all the handlers in a WeakSet". I couldn't get it to work.
I dump here the code (or what's left of it when I reduce it to the minimum, here there's only one type of event and only one type of handler).
#! /usr/bin/python
"""
"""
import sys
import weakref
class Listener(object):
def handler(self, event):
print event
class EventManager(object):
def __init__(self):
self.handlers = weakref.WeakSet()
def register(self, listener):
print "Registering..."
self.handlers.add(listener.handler)
CountRefs(listener.handler)
print "Number of handlers registered:", len(self.handlers)
print "Registered."
def CountRefs(what):
print "Hard count:", sys.getrefcount(what)
print "Weak count:", weakref.getweakrefcount(what)
listener = Listener()
em = EventManager()
CountRefs(listener.handler)
em.register(listener)
CountRefs(listener.handler)
result:
Hard count: 3
Weak count: 0
Registering...
Hard count: 3
Weak count: 0
Number of handlers registered: 0
Registered.
Hard count: 3
Weak count: 0
It just looks like there's never any weak reference, and the set remains empty.
To make it even simpler:
>>> class C(object):
>>> def blah(self):
>>> print "blah"
>>>
>>> c = C()
>>> w = weakref.ref(c.blah)
>>> print w
<weakref at 0x11e59f0; dead>
Can't I create weakrefs to methods at all ? If not, why not ?
So I guess a workaround would be to replace the WeakSet with a WeakKeyDictionary: key is the listener itself, and value the handler. Indeed I can weakref my Listeners. But it makes the data structure a bit more complicated, and when comes the time to broadcast the events to everybody, there's one more level in that structure to go through.
What do you think ?