-
Notifications
You must be signed in to change notification settings - Fork 0
/
observer.py
41 lines (36 loc) · 1.52 KB
/
observer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class Observer(object):
"""An observer, initiated with a callback will notify
callback of new value on value change."""
def __init__(self, callback, default=None):
self._callback = callback
# a default value should be passed so attempting to increment
# an observed object (before being set)
# doesn't result in attribute error.
self._default = default
def __get__(self, instance, owner):
"""Get the hidden observable."""
if instance is None:
raise AttributeError("Not a class attribute, access from instance")
try:
return instance._observable
except AttributeError:
instance._observable = self._default
# notify the callback that the observable has changed.
self._callback(self._default)
return instance._observable
def __set__(self, instance, value):
"""Set the hidden attribute and notify callback."""
if instance is None:
raise AttributeError("Cannot set class attribute, use instance.")
# notify the callback.
self._callback(value)
# now change the value.
instance._observable = value
def __delete__(self, instance):
"""remove the attribute and notify callback."""
if instance is None:
raise AttributeError("Cannot remove class attribute.")
# set callback value to None.
self._callback(None)
# now set observable to None.
instance._observable = None