Python decorators that are part of a base class cannot be used to decorate member functions in inherited classes
You need to make UpdateGUI
a @classmethod
, and make your wrapper
aware of self
. A working example:
class X(object): @classmethod def foo(cls, fun): def wrapper(self, *args, **kwargs): self.write(*args, **kwargs) return fun(self, *args, **kwargs) return wrapper def write(self, *args, **kwargs): print(args, kwargs)class Y(X): @X.foo def bar(self, x): print("x:", x)Y().bar(3)# prints:# (3,) {}# x: 3
It might be easier to just pull the decorator out of the SubSytem
class:(Note that I'm assuming that the self
that calls setport
is the same self
that you wish to use to call updateGUIField
.)
def UpdateGUI(fun): #function decorator def wrapper(self,*args): self.updateGUIField(*args) return fun(self,*args) return wrapperclass SubSystem(object): 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 print(name,value)class DO(SubSystem): @UpdateGUI def setport(self, port, value): """Sets the value of Digital Output port "port".""" passdo=DO()do.setport('p','v')# ('p', 'v')
You've sort of answered the question in asking it: what argument would you expect to get as self
if you call SubSystem.UpdateGUI
? There isn't an obvious instance that should be passed to the decorator.
There are several things you could do to get around this. Maybe you already have a subSystem
that you've instantiated somewhere else? Then you could use its decorator:
subSystem = SubSystem()subSystem.UpdateGUI(...)
But maybe you didn't need the instance in the first place, just the class SubSystem
? In that case, use the classmethod
decorator to tell Python that this function should receive its class as the first argument instead of an instance:
@classmethoddef UpdateGUI(cls,...): ...
Finally, maybe you don't need access to either the instance or the class! In that case, use staticmethod
:
@staticmethoddef UpdateGUI(...): ...
Oh, by the way, Python convention is to reserve CamelCase names for classes and to use mixedCase or under_scored names for methods on that class.