Ich selbst bin eigentlich stark von C++ und n bisschen 90er-Java geprägt. Aber ich arbeite bereits lange genug mit Python, um zu wissen, dass hier einiges anders und einfacher laufen kann.
Basierend auf diversen StackOverflow-Antworten habe ich dieses Beispiel konstruiert, in dem nur ein Datenobjekt und ein GUI-Element (simuliert) existiert.
Code: Alles auswählen
# basiert auf https://stackoverflow.com/a/44499893/4865723
class Observable:
"""
The object that need to be observed. Alternative names are 'Subject'.
In the most cases it is a data object.
"""
def __init__(self):
self._observers = []
def register_observer(self, callback):
"""
"""
self._observers.append(callback)
def _broadcast_observers(self, *args, **kwargs):
"""
"""
for callback in self._observers:
callback(*args, **kwargs)
class TheData(Observable):
"""
Example of a data class just for demonstration.
"""
def __init__(self, data):
Observable.__init__(self)
self._data = data
@property
def data(self):
return self._data
@data.setter
def data(self, data):
self._data = data
self._broadcast_observers()
class TheGUIElement:
"""
Example of a gui class (Widget) just for demonstration.
e. g. it could be a text field in GUI.
"""
def __init__(self, data):
self._data = data
data.register_observer(self._data_updated)
self._redraw()
def _redraw(self):
print('in _redraw(): ' + data.data)
def _data_updated(self, **kwargs):
"""
This is the callback that is called by the Observable if the
data changed.
"""
print('in _data_updated() - kwargs: {}'.format(kwargs))
self._redraw()
if __name__ == '__main__':
data = TheData('DATA')
gui = TheGUIElement(data)
data.data = 'SECOND DATA'