observer.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """http://code.activestate.com/recipes/131499-observer-pattern/"""
  4. class Subject(object):
  5. def __init__(self):
  6. self._observers = []
  7. def attach(self, observer):
  8. if observer not in self._observers:
  9. self._observers.append(observer)
  10. def detach(self, observer):
  11. try:
  12. self._observers.remove(observer)
  13. except ValueError:
  14. pass
  15. def notify(self, modifier=None):
  16. for observer in self._observers:
  17. if modifier != observer:
  18. observer.update(self)
  19. # Example usage
  20. class Data(Subject):
  21. def __init__(self, name=''):
  22. Subject.__init__(self)
  23. self.name = name
  24. self._data = 0
  25. @property
  26. def data(self):
  27. return self._data
  28. @data.setter
  29. def data(self, value):
  30. self._data = value
  31. self.notify()
  32. class HexViewer:
  33. def update(self, subject):
  34. print('HexViewer: Subject %s has data 0x%x' %
  35. (subject.name, subject.data))
  36. class DecimalViewer:
  37. def update(self, subject):
  38. print('DecimalViewer: Subject %s has data %d' %
  39. (subject.name, subject.data))
  40. # Example usage...
  41. def main():
  42. data1 = Data('Data 1')
  43. data2 = Data('Data 2')
  44. view1 = DecimalViewer()
  45. view2 = HexViewer()
  46. data1.attach(view1)
  47. data1.attach(view2)
  48. data2.attach(view2)
  49. data2.attach(view1)
  50. print("Setting Data 1 = 10")
  51. data1.data = 10
  52. print("Setting Data 2 = 15")
  53. data2.data = 15
  54. print("Setting Data 1 = 3")
  55. data1.data = 3
  56. print("Setting Data 2 = 5")
  57. data2.data = 5
  58. print("Detach HexViewer from data1 and data2.")
  59. data1.detach(view2)
  60. data2.detach(view2)
  61. print("Setting Data 1 = 10")
  62. data1.data = 10
  63. print("Setting Data 2 = 15")
  64. data2.data = 15
  65. if __name__ == '__main__':
  66. main()
  67. ### OUTPUT ###
  68. # Setting Data 1 = 10
  69. # DecimalViewer: Subject Data 1 has data 10
  70. # HexViewer: Subject Data 1 has data 0xa
  71. # Setting Data 2 = 15
  72. # HexViewer: Subject Data 2 has data 0xf
  73. # DecimalViewer: Subject Data 2 has data 15
  74. # Setting Data 1 = 3
  75. # DecimalViewer: Subject Data 1 has data 3
  76. # HexViewer: Subject Data 1 has data 0x3
  77. # Setting Data 2 = 5
  78. # HexViewer: Subject Data 2 has data 0x5
  79. # DecimalViewer: Subject Data 2 has data 5
  80. # Detach HexViewer from data1 and data2.
  81. # Setting Data 1 = 10
  82. # DecimalViewer: Subject Data 1 has data 10
  83. # Setting Data 2 = 15
  84. # DecimalViewer: Subject Data 2 has data 15