1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """
22 Subject and Observer classes to implement the Model-View-Controller pattern.
23 """
24
25 import weakref
26
28 """Instances of Observer are notified of changes happening in the
29 Subject instances they are attached to.
30 It's possible for an Observer to watch many Subject.
31 """
32
34 self.subjects = []
35 if isinstance(subjects, tuple):
36 for subject in subjects:
37 self.append(subject)
38 else:
39 self.append(subjects)
40
42 """
43 Adds a subject to be observed by this Observer instance.
44 """
45 if isinstance(subject, Subject):
46 self.subjects.append(subject)
47 subject._attach(self)
48
49
50 - def update(self, origin, key, value):
51 """Called when an attribute of the observed object is changed.
52 Should be overridden.
53
54 @param origin: observed object for which the attribute is changed (caller)
55 @type origin: any
56 @param key: attribute changed (default to the function that called it. in api.py)
57 @type key: string
58 @param value: value of the attribute after being set
59 @type value: any
60 """
61 raise NotImplementedError
62
63
65 """
66 Subject watched by an Observer.
67
68 This can be the "Model" in the Model-View-Controller pattern.
69 """
71 self.observers = weakref.WeakValueDictionary()
72
74 ob_id = id(observer)
75 if ob_id not in self.observers:
76 self.observers[ob_id] = observer
77
78 - def notify(self, caller, value, key=None):
79 """
80 Calls all its observers that an attribute has changed.
81
82 Usage: self.notify(self,'brown','color')
83 WARNING: the signature has changed since miville.
84 args key and valud have been interchanged.
85 """
86 if not key:
87 raise Exception("Warning: support for None keys has been removed")
88
89 for observer in self.observers.itervalues():
90 observer.update(caller, key, value)
91