patternpythonMinor
Three implementations of observable objects
Viewed 0 times
threeimplementationsobjectsobservable
Problem
I wonder, what might be the best (most pythonic) way of implementing multiple observerables in Python. There are multiple objects, which should be able to register themselves at one or multiple observables.
Shall I simply submit the update methods, like this:
Or is it better, to come up with a dictionary of classes and methods:
```
class DictObservable():
def __init__(self, data_source):
self.observers = {}
self.data_source = data_source
def add(self, observer, callback):
self.observers[observer] = callback
def remove(self, observer):
try:
del self.observers[observer]
except ValueError:
pass
def notify():
for callback in self.observers.values():
callback(self.data_source)
class DictObserver():
def __init__(self, observer1, observer2):
observer1.add(self, self.update_for_1)
observer2.add(self, self.update_for_2)
def update_for_1(self, data_source):
# code
def update_for_2(self, data_source):
# code
data_source1 = SomeObject
Shall I simply submit the update methods, like this:
class MethodObservable():
def __init__(self, data_source):
self.observers = []
self.data_source = data_source
def add(self, callback):
self.observers.add(callback)
def remove(self, callback):
try:
self.observers.remove(callback)
except ValueError:
pass
def notify():
for callback in self.observers:
callback(self.data_source)
class MethodObserver():
def __init__(self, observer1, observer2):
observer1.add(self.update_for_1)
observer2.add(self.update_for_2)
def update_for_1(self, data_source):
# code
def update_for_2(self, data_source):
# code
data_source1 = SomeObject()
data_source2 = SomeOtherObject()
observable1 = MethodObservable(data_source1)
observable2 = MethodObservable(data_source2)
observer = MethodObserver(observable1, observable2)Or is it better, to come up with a dictionary of classes and methods:
```
class DictObservable():
def __init__(self, data_source):
self.observers = {}
self.data_source = data_source
def add(self, observer, callback):
self.observers[observer] = callback
def remove(self, observer):
try:
del self.observers[observer]
except ValueError:
pass
def notify():
for callback in self.observers.values():
callback(self.data_source)
class DictObserver():
def __init__(self, observer1, observer2):
observer1.add(self, self.update_for_1)
observer2.add(self, self.update_for_2)
def update_for_1(self, data_source):
# code
def update_for_2(self, data_source):
# code
data_source1 = SomeObject
Solution
First thing, you should use new-style classes, inheriting from
So, in short, your choices are:
Of the two, the dictionary is the best option, because the keys are stored in a hash table, and you can look up items in O(1), whereas in the list you have to transverse the whole thing until you find it, so it is O(N).
Now, note that your dictionary implementation is a very thin layer on top of a dict. I would recommend inheriting from
Note that the third method is broken. In particular:
when
object. (Not necessary if you are in Python3, but convenient for backwards compatibility).So, in short, your choices are:
- Store them in a list
- Store them in a dictionary
Of the two, the dictionary is the best option, because the keys are stored in a hash table, and you can look up items in O(1), whereas in the list you have to transverse the whole thing until you find it, so it is O(N).
Now, note that your dictionary implementation is a very thin layer on top of a dict. I would recommend inheriting from
dict. If you are bound to the specific interface (.add, .remove) instead of the __setitem__ and pop, you can just create aliases. This can help you reduce the amount of code and also give you easier access to all the expresiveness of Python dicts.Note that the third method is broken. In particular:
self.observers.add(observer)when
self.observers is a list, that doesn't have the method add.Code Snippets
self.observers.add(observer)Context
StackExchange Code Review Q#57804, answer score: 2
Revisions (0)
No revisions yet.