作为基类一部分的 Python 装饰器不能用于装饰继承类中的成员函数
回答问题 Python 装饰器使用起来很有趣,但由于参数传递给装饰器的方式,我似乎碰壁了。在这里,我将一个装饰器定义为基类的一部分(装饰器将访问类成员,因此它需要 self 参数)。 class SubSystem(object): def UpdateGUI(self, fun): #function decorator def wrapper(*args): self.updateGUIFie
·
回答问题
Python 装饰器使用起来很有趣,但由于参数传递给装饰器的方式,我似乎碰壁了。在这里,我将一个装饰器定义为基类的一部分(装饰器将访问类成员,因此它需要 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
我再次省略了函数实现,因为它们不相关。
简而言之,问题是虽然我可以通过将继承类中定义的装饰器指定为 SubSystem.UpdateGUI 来访问基类中定义的装饰器,但在尝试使用它时最终会得到这个 TypeError:
unbound method UpdateGUI() must be called with SubSystem instance as first argument (got function instance instead)
这是因为我没有立即可识别的方式将self
参数传递给装饰器!
有没有办法做到这一点?还是我已经达到了 Python 中当前装饰器实现的极限?
Answers
您需要将UpdateGUI
设置为@classmethod
,并让您的wrapper
了解self
。一个工作示例:
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
更多推荐
已为社区贡献126483条内容
所有评论(0)