Odalrick wrote: > I'm trying to write a simple game and decided I need an eventmanager. > > <code> > import weakref > from collections import defaultdict > > class _EventManager( object ): > def __init__( self ): > self._handled_events = > defaultdict( weakref.WeakKeyDictionary ) > > def register( self, handler, event_type, filter=None ): > self._handled_events[event_type][handler] = filter > > def deregister( self, handler, event_type ): > self._handled_events[event_type].pop( handler, None ) > > def handle_event( self, event ): > event_type = event.type > for handler, filter in > self._handled_events[event_type].items(): > if filter == None or filter(event): > handler( event ) > > eventmanager = _EventManager() > > __all__ = [ eventmanager ] > </code> > > Fairly simple, yet there was some strange bug that prevented my game > from exiting. > > I think what happened was that when __init__ ends, self goes out of > scope, and by extension so does self.handle_quit, Now there are no > more refeences to self.handle_quit, because weakrefs don't count, and > the event gets automatically dropped from my eventmanager. I thought > that wouldn't happen because handle_quit is part of the class and > instance MainGame.
No, self is yet another reference to the _EventManager instance which survives the __init__() call because it is also referenced by the global variable eventmanager. On the other hand, self.handle_quit creates a new bound-method object every time which doesn't even live as long as __init__(). > Am I right in my guess? If so, how should I adress this bug? If not, > what is the bug? The easiest option, to forget about weakrefs, seems to be the best here. The other option is to keep a reference to the bound method, e. g.: class MainGame(object): def __init__(self, ...): # put a bound method into the MainGame instance # you can use a different attribute name if you want hq = self.handle_quit = self.handle_quit # register it eventmanager.register(hq, ...) Peter -- http://mail.python.org/mailman/listinfo/python-list