Python decorators使用起来很有趣,但由于参数传递给decorators的方式,我似乎遇到了麻烦。在这里,我将decorator定义为基类的一部分(decorator将访问类成员,因此它将需要self参数)。
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
...
我省略了其余的实现。现在这个类是继承自它的各种子系统的基类——一些继承的类需要使用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
我再次省略了函数实现,因为它们不相关。
简而言之,问题是,虽然我可以通过将基类中定义的decorator指定为SubSystem.UpdateGUI来从继承的类访问它,但在尝试使用它时,我最终会得到这个TypeError:
unbound method UpdateGUI() must be called with SubSystem instance as first argument (got function instance instead)
这是因为我没有立即将self
参数传递给decorator的可识别方法!
有办法吗?或者我达到了Python中当前decorator实现的极限了吗?
你已经回答了这个问题:如果你调用
SubSystem.UpdateGUI
,你希望得到什么样的参数作为self
?没有明显的实例应该传递给decorator。你可以做几件事来解决这个问题。也许你已经有了一个在其他地方实例化的
subSystem
?然后你可以用它的装饰器:但也许你一开始就不需要这个实例,只需要类
SubSystem
?在这种情况下,使用classmethod
decorator告诉Python该函数应该将其类作为第一个参数而不是实例来接收:最后,也许您不需要访问实例或类!在这种情况下,使用
staticmethod
:哦,顺便说一下,Python约定是为类保留CamelCase名称,并为该类上的方法使用mixedCase或under_scored名称。
你需要让
UpdateGUI
成为@classmethod
,让你的wrapper
意识到self
。一个有效的例子:将decorator从
SubSytem
类中拉出可能更容易: (注意,我假设调用setport
的self
与您希望用来调用updateGUIField
的self
相同。)相关问题 更多 >
编程相关推荐