import json class NotImplementedException(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) class Subscriber: def __init__(self, name): self.name = name def update(self, event, param=None): #print('{} got message "{}"'.format(self.name, message)) raise NotImplementedException('update function is not implemented! Override the function by subclassing Subscriber!') class Publisher: def __init__(self, events): # maps event names to subscribers # str -> dict self.events = { event : dict() for event in events } def get_subscribers(self, event): return self.events[event] def register(self, event, who, callback=None): if callback == None: callback = getattr(who, 'update') self.get_subscribers(event)[who] = callback def unregister(self, event, who): del self.get_subscribers(event)[who] def dispatch(self, event, params=None): for subscriber, callback in self.get_subscribers(event).items(): callback(event, params) ############################################################# # Test classes to demo usage of Publisher and Subscriber # # class Producer(Publisher): def __init__(self, events): Publisher.__init__(self, events) class Consumer(Subscriber): def __init__(self, name): Subscriber.__init__(self, name) def update(self, event, param=None): print('override %s: %s %s %s' % (self.name, event, "" if not param else param, '' if not param else param.__class__)) def trigger(self, event, param=None): print('trigger %s: %s %s %s' % (self.name, event, "" if not param else param, '' if not param else param.__class__)) if __name__ == '__main__': p = Producer(['e1', 'e2']) bb = Consumer('bb') cc = Consumer('cc') p.register('e1', bb) p.register('e1', cc, cc.trigger) p.register('e2', cc) p.dispatch('e1', {'xx':123, 'yy':444}) p.dispatch('e2', str({'x':123, 'y':444}))