Los decoradores de Python son divertidos, pero parece que se han pegado a la pared debido a la forma en que se transmiten los argumentos a los decoradores. Aquí tengo un decorador definido como parte de una clase base (el decorador tendrá acceso a los miembros de la clase, por lo tanto, requerirá el parámetro automático).Los decoradores de Python que forman parte de una clase base no se pueden usar para decorar las funciones de los miembros en las clases heredadas
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
...
He omitido el resto de la implementación. Ahora esta clase es una clase base para varios subsistemas que heredarán de ella; algunas de las clases heredadas necesitarán usar el decorador 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
Una vez más me han omitido las implementaciones de funciones, ya que no son relevantes.
En resumen, el problema es que mientras pueda acceder al decorador definidos en la clase base de la clase heredada por specifiying como SubSystem.UpdateGUI, que en última instancia conseguir este TypeError cuando se trata de usarlo:
unbound method UpdateGUI() must be called with SubSystem instance as first argument (got function instance instead)
Esto se debe a que no tengo una forma inmediatamente identificable de pasar el parámetro self
al decorador.
¿Hay alguna manera de hacerlo? ¿O alcancé los límites de la implementación del decorador actual en Python?
Esto funcionó! Nunca se hubiera pensado en convertir al decorador en un método de clase. – Aphex
Para referencia futura, esta fue literalmente una corrección de línea al agregar @classmethod antes de def UpdateGUI (self, fun). – Aphex
@Aphex. debe reemplazar el uso de 'self' con el uso de' cls' como KennyTM mostró. Esto hará que su código sea mucho más fácil de leer. – aaronasterling