observer.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import json
  2. class NotImplementedException(Exception):
  3. def __init__(self, value):
  4. self.value = value
  5. def __str__(self):
  6. return repr(self.value)
  7. class Subscriber:
  8. def __init__(self, name):
  9. self.name = name
  10. def update(self, event, param=None):
  11. #print('{} got message "{}"'.format(self.name, message))
  12. raise NotImplementedException('update function is not implemented! Override the function by subclassing Subscriber!')
  13. class Publisher:
  14. def __init__(self, events):
  15. # maps event names to subscribers
  16. # str -> dict
  17. self.events = { event : dict()
  18. for event in events }
  19. def get_subscribers(self, event):
  20. return self.events[event]
  21. def register(self, event, who, callback=None):
  22. if callback == None:
  23. callback = getattr(who, 'update')
  24. self.get_subscribers(event)[who] = callback
  25. def unregister(self, event, who):
  26. del self.get_subscribers(event)[who]
  27. def dispatch(self, event, params=None):
  28. for subscriber, callback in self.get_subscribers(event).items():
  29. callback(event, params)
  30. #############################################################
  31. # Test classes to demo usage of Publisher and Subscriber
  32. #
  33. #
  34. class Producer(Publisher):
  35. def __init__(self, events):
  36. Publisher.__init__(self, events)
  37. class Consumer(Subscriber):
  38. def __init__(self, name):
  39. Subscriber.__init__(self, name)
  40. def update(self, event, param=None):
  41. print('override %s: %s %s %s' % (self.name, event, "<empy param>" if not param else param,
  42. '<none>' if not param else param.__class__))
  43. def trigger(self, event, param=None):
  44. print('trigger %s: %s %s %s' % (self.name, event, "<empy param>" if not param else param,
  45. '<none>' if not param else param.__class__))
  46. if __name__ == '__main__':
  47. p = Producer(['e1', 'e2'])
  48. bb = Consumer('bb')
  49. cc = Consumer('cc')
  50. p.register('e1', bb)
  51. p.register('e1', cc, cc.trigger)
  52. p.register('e2', cc)
  53. p.dispatch('e1', {'xx':123, 'yy':444})
  54. p.dispatch('e2', str({'x':123, 'y':444}))