Skip to content

Commit fb35b1e

Browse files
authored
Merge pull request #345 from rednafi/master
Added type hints to observer pattern
2 parents d7219ff + daa2219 commit fb35b1e

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

patterns/behavioral/observer.py

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,64 @@
55
Maintains a list of dependents and notifies them of any state changes.
66
77
*Examples in Python ecosystem:
8-
Django Signals: https://docs.djangoproject.com/en/2.1/topics/signals/
9-
Flask Signals: http://flask.pocoo.org/docs/1.0/signals/
8+
Django Signals: https://docs.djangoproject.com/en/3.1/topics/signals/
9+
Flask Signals: https://flask.palletsprojects.com/en/1.1.x/signals/
1010
"""
1111

12+
from __future__ import annotations
13+
14+
from contextlib import suppress
15+
from typing import List, Optional, Protocol
16+
17+
18+
# define a generic observer type
19+
class Observer(Protocol):
20+
def update(self, subject: Subject) -> None:
21+
pass
22+
1223

1324
class Subject:
14-
def __init__(self):
15-
self._observers = []
25+
def __init__(self) -> None:
26+
self._observers: List[Observer] = []
1627

17-
def attach(self, observer):
28+
def attach(self, observer: Observer) -> None:
1829
if observer not in self._observers:
1930
self._observers.append(observer)
2031

21-
def detach(self, observer):
22-
try:
32+
def detach(self, observer: Observer) -> None:
33+
with suppress(ValueError):
2334
self._observers.remove(observer)
24-
except ValueError:
25-
pass
2635

27-
def notify(self, modifier=None):
36+
def notify(self, modifier: Optional[Observer] = None) -> None:
2837
for observer in self._observers:
2938
if modifier != observer:
3039
observer.update(self)
3140

3241

3342
class Data(Subject):
34-
def __init__(self, name=""):
35-
Subject.__init__(self)
43+
def __init__(self, name: str = "") -> None:
44+
super().__init__()
3645
self.name = name
3746
self._data = 0
3847

3948
@property
40-
def data(self):
49+
def data(self) -> int:
4150
return self._data
4251

4352
@data.setter
44-
def data(self, value):
53+
def data(self, value: int) -> None:
4554
self._data = value
4655
self.notify()
4756

4857

4958
class HexViewer:
50-
def update(self, subject):
51-
print(
52-
"HexViewer: Subject {} has data 0x{:x}".format(subject.name, subject.data)
53-
)
59+
def update(self, subject: Data) -> None:
60+
print(f"HexViewer: Subject {subject.name} has data 0x{subject.data:x}")
5461

5562

5663
class DecimalViewer:
57-
def update(self, subject):
58-
print("DecimalViewer: Subject %s has data %d" % (subject.name, subject.data))
64+
def update(self, subject: Data) -> None:
65+
print(f"DecimalViewer: Subject {subject.name} has data {subject.data}")
5966

6067

6168
def main():

0 commit comments

Comments
 (0)