Python-Dekoratoren, die Teil einer Basisklasse sind, können nicht zum Dekorieren von Memberfunktionen in geerbten Klassen verwendet werden.
ie Verwendung von @Python-Dekoratoren macht Spaß, aber anscheinend bin ich auf Grund der Art und Weise, wie Argumente an Dekoratoren übergeben werden, an eine Wand gestoßen. Hier habe ich einen Decorator als Teil einer Basisklasse definiert (der Decorator greift auf Klassenmitglieder zu, daher wird der Parameter self benötigt).
class SubSystem(object):
def UpdateGUI(self, fun): #function decorator
def wrapper(*args):
self.updateGUIField(*args)
return fun(*args)
return wrapper
def updateGUIField(self, name, value):
if name in self.gui:
if type(self.gui[name]) == System.Windows.Controls.CheckBox:
self.gui[name].IsChecked = value #update checkbox on ui
elif type(self.gui[name]) == System.Windows.Controls.Slider:
self.gui[name].Value = value # update slider on ui
...
Ich habe den Rest der Implementierung weggelassen. Diese Klasse ist nun eine Basisklasse für verschiedene Subsysteme, die von ihr erben. Einige der geerbten Klassen müssen den UpdateGUI-Dekorator verwenden.
class DO(SubSystem):
def getport(self, port):
"""Returns the value of Digital Output port "port"."""
pass
@SubSystem.UpdateGUI
def setport(self, port, value):
"""Sets the value of Digital Output port "port"."""
pass
Einmal habe ich die Funktionsimplementierungen weggelassen, da sie nicht relevant sind.
urz gesagt, das Problem ist, dass ich auf den in der Basisklasse definierten Decorator von der geerbten Klasse aus zugreifen kann, indem ich ihn als SubSystem.UpdateGUI spezifiziere. Letztendlich erhalte ich diesen TypeError, wenn ich versuche, ihn zu verwenden:
unbound method UpdateGUI() must be called with SubSystem instance as first argument (got function instance instead)
Das liegt daran, dass ich keine sofort identifizierbare Möglichkeit habe, das @ weiterzuleiteself
Parameter an den Dekorateur!
Gibt es eine Möglichkeit, dies zu tun? Oder bin ich an die Grenzen der aktuellen Decorator-Implementierung in Python gestoßen?