I decoratori Python sono divertenti da usare, ma sembra che abbia colpito un muro a causa del modo in cui gli argomenti vengono passati ai decoratori. Qui ho un decoratore definito come parte di una classe base (il decoratore accederà ai membri della classe quindi richiederà il parametro auto).I decoratori Python che fanno parte di una classe base non possono essere usati per decorare le funzioni membro nelle classi ereditate
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
...
Ho omesso il resto dell'implementazione. Ora questa classe è una classe base per vari sottosistemi che erediteranno da esso: alcune delle classi ereditate dovranno utilizzare il decoratore UpdateGUI.
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
Ancora una volta ho omesso le implementazioni di funzione in quanto non pertinenti.
In breve, il problema è che mentre posso accedere decoratore definito nella classe base dalla classe ereditata da specifiying come SubSystem.UpdateGUI, ho infine ottenere questo TypeError quando si tenta di usarlo:
unbound method UpdateGUI() must be called with SubSystem instance as first argument (got function instance instead)
Questo perché non ho un modo immediatamente identificabile per passare il parametro self
al decoratore!
C'è un modo per farlo? O ho raggiunto i limiti dell'attuale implementazione del decoratore in Python?
Questo ha funzionato! Non avrei mai pensato di trasformare il decoratore in un metodo di classe. – Aphex
Per riferimento futuro, questa è stata letteralmente una correzione su una riga aggiungendo @classmethod prima di def UpdateGUI (self, fun). – Aphex
@Aphex. dovresti sostituire l'uso di 'self' con l'uso di' cls' come mostrato da KennyTM. Questo renderà il tuo codice molto più facile da leggere. – aaronasterling