Possible duplicate:
Why does weakref not work on this related method?
A bit of context:
I tried to implement the Listener template (or Observer, the same one): EventManager stores a list of all Listeners handlers interested in the event. For example, the Listener object will have a method onEndOfTheWorldEventthat will be called by the EventManager each time it exposes an instance of the EndOfTheWorldEvent event class. Easy.
Except that I would like to weakly reference handlers, because I do not want the EventManager to keep my handlers (related methods) alive when the Listener is no longer needed.
So I thought, "Drop all handlers in WeakSet." I could not get it to work.
I will give the code here (or what remains of it, when I reduce it to a minimum, there is only one type of event and only one type of handler).
"""
"""
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 seems like there is never a weak link and the set remains empty.
Make it even easier:
>>> 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 for methods in general? If not, why not ?
So, I think a workaround would be to replace WeakSet with WeakKeyDictionary: key is the listener itself and the value of the handler. In fact, I can weaken my listeners. But this makes the data structure a little more complex, and when it comes time to broadcast events for everyone, there is another level in this structure to go through.
What do you think?