Seite 1 von 1
Attribute einer anderen Klasse überwachen?
Verfasst: Mittwoch 9. August 2017, 15:11
von Kniffte
Hallo Zusammen,
Wie kann ich in einer übergeordneten Klasse, in der zwei Instanzen einer anderen Klasse erzeugt wurden, die Attribute der beiden Instanzen überwachen? Wenn sich ein Attribut in 'dataset_main_blade' ändert, soll eine Funktion 'match_values()' aufgerufen werden, die dann das Attribut in 'dataset_splitter_blade' auf den gleichen wert setzt.
Code: Alles auswählen
class Wheel:
def __init__(self):
self.dataset_main_blade = Dataset()
self.dataset_splitter_blade = Dataset()
# if shroud value changed in dataset_main_blade -->
# set shroud value in dataset_splitter_blade to the same value
# match_values()
def match_values(self):
self.dataset_splitter_blade.shroud_value = self.dataset_main_blade.shroud_value
class Dataset:
def __init__(self):
self._shroud_value = 0
self._hub_value = 0
@property
def shroud_value(self):
return self._shroud_value
@shroud_value.setter
def shroud_value(self, value):
print('previous actions...')
self._shroud_value = value
print('shroud value set to', value)
@property
def hub_value(self):
return self._hub_value
@hub_value.setter
def hub_value(self, value):
print('previous actions')
self._hub_value = value
print('hub value set to', value)
Re: Attribute einer anderen Klasse überwachen?
Verfasst: Mittwoch 9. August 2017, 15:53
von __deets__
Klingt danach als ob dir reactive programming helfen koennte. Dafuer gibt's diverse Bibliotheken, benutzt habe ich bis dato selbst keine - schreibe eine im Moment fuer GPIOs, das ist aber noch zu frueh um damit etwas machen zu koennen. Aber google mal nach "reactive programming python", da finden sich Dinge.
Re: Attribute einer anderen Klasse überwachen?
Verfasst: Donnerstag 10. August 2017, 17:56
von Kniffte
Danke für den Hinweis __deets__. Wenn ich es richtig verstanden haben, dann wäre das auf jeden Fall eine Möglichkeit meine Anwendung zu verbessern. Nur fällt es mir grad schwer z.B.
RxPY gut genug zu verstehen, dass ich es in meine Anwendung einbringen könnte.
Zwischenzeitlich hab ich noch selbst etwas gebastelt, was ohne zusätzliche Bibliothek auskommen würde.
(Vielleicht ist das ja auch etwas "reactive", da ich mich an Observer Pattern orientiert habe?)
Gibt es in meiner aktuellen Variante Fehler, Probleme oder Mängel, die mir nicht auffallen?
Code: Alles auswählen
class Wheel:
def __init__(self):
self._changed_observable = None
self.dataset_main_blade = Dataset('dataset_main_blade', self)
self.dataset_splitter_blade = Dataset('dataset_splitter_blade', self)
self.events = {
'dataset_main_blade_shroud_value':self.match_shroud_values
}
@property
def changed_observable(self):
return self._changed_observable
@changed_observable.setter
def changed_observable(self, value):
self._changed_observable = value
if self._changed_observable in self.events:
self.events[self._changed_observable]()
self._changed_observable = None
def match_shroud_values(self):
print('match_shroud_values called...')
self.dataset_splitter_blade.shroud_value = self.dataset_main_blade.shroud_value
class Dataset:
def __init__(self, instance_name, observer):
self.instance_name = instance_name
self.observer = observer
self._shroud_value = 0
self._hub_value = 0
@property
def shroud_value(self):
return self._shroud_value
@shroud_value.setter
def shroud_value(self, value):
self._shroud_value = value
print(self.instance_name, 'shroud value set to', value)
self.observer.changed_observable = '{}_{}'.format(self.instance_name, 'shroud_value')
@property
def hub_value(self):
return self._hub_value
@hub_value.setter
def hub_value(self, value):
self._hub_value = value
print(self.instance_name, 'hub value set to', value)
self.observer.changed_observable = '{}_{}'.format(self.instance_name, 'hub_value')
if __name__ == '__main__':
cw = Wheel()
cw.dataset_main_blade.shroud_value = 2
Re: Attribute einer anderen Klasse überwachen?
Verfasst: Montag 14. August 2017, 10:18
von __deets__
Fuer mein Verstaendnis ist reactive Programming weniger explizit. Natuerlich ist das Observer-Pattern eine notwendige Vorraussetzung, ohne solche Arten von Ereignissen geht's nicht.
Aber die Benutzung sieht etwas krepelig aus, sehr viel Boilerplate. Reactive Programming versucht das einzudaemmen. Im Idealfall kombiniert man das noch mit "view-as-a-function" (da gibt's glaube ich noch einen besseren Namen fuer, der mir gerade nicht einfaellt), und dann hat man da eine aufgeraeumtere Implementierung, die sich zB auch nicht implizit auf die Reihenfolge von Ereignissen verlaesst - das ist naemlich eine der grossen Herausforderungen bei Observables.
Re: Attribute einer anderen Klasse überwachen?
Verfasst: Montag 14. August 2017, 15:09
von Alfons Mittelmeyer
Kniffte hat geschrieben:Hallo Zusammen,
Wie kann ich in einer übergeordneten Klasse, in der zwei Instanzen einer anderen Klasse erzeugt wurden, die Attribute der beiden Instanzen überwachen? Wenn sich ein Attribut in 'dataset_main_blade' ändert, soll eine Funktion 'match_values()' aufgerufen werden, die dann das Attribut in 'dataset_splitter_blade' auf den gleichen wert setzt.
Dann kann man das so sehen, dass die erzeugene Klasse der parent ist und die erzeugten Instanzen sind die children. Dann brauchen die children noch ein Attribut, nämlich den Parent. Dann können sie auch die match methode des parents aufrufen und wenn sie dabei auch noch ihr self mitgeben, weiß der parent, woher es kommt und kann das dann auch noch beim anderen child setzten oder er braucht es nicht wissen, sondern setzt es dann einfach für beide. Diese set Methode muß aber eine andere sein als die, welche das match des parents aufruft.
Also, nicht der Parent überwacht, sondern die set Methode der children ruft die Methode des parents auf.
Re: Attribute einer anderen Klasse überwachen?
Verfasst: Montag 14. August 2017, 16:45
von kbr
@Kniffte: Wenn es nicht allzu generisch sein soll, könnte dies vielleicht ein Ansatz sein:
Code: Alles auswählen
class Wheel:
def __init__(self):
self.dataset_main_blade = Dataset(supervisor=self)
self.dataset_splitter_blade = Dataset()
def match_values(self, data):
self.dataset_splitter_blade.__dict__.update(data)
class Dataset:
def __init__(self, supervisor=None):
self._shroud_value = 0
self._hub_value = 0
self.supervisor = supervisor
@property
def shroud_value(self):
return self._shroud_value
@shroud_value.setter
def shroud_value(self, value):
self._shroud_value = value
print('shroud value set to', value)
self._report_supervisor()
@property
def hub_value(self):
return self._hub_value
@hub_value.setter
def hub_value(self, value):
self._hub_value = value
print('hub value set to', value)
self._report_supervisor()
def _report_supervisor(self):
if self.supervisor:
self.supervisor.match_values(self.__dict__)
if __name__ == '__main__':
cw = Wheel()
cw.dataset_main_blade.shroud_value = 2
print(cw.dataset_main_blade.shroud_value)
print(cw.dataset_splitter_blade.shroud_value)