问题描述
Python装饰器使用起来很有趣,但由于参数传递给装饰器的方式,我似乎遇到了障碍。这里我有一个装饰器被定义为基类的一部分(装饰器将访问类成员,因此它将需要self参数)。
Python decorators are fun to use, but I appear to have hit a wall due to the way arguments are passed to decorators. Here I have a decorator defined as part of a base class (the decorator will access class members hence it will require the self parameter).
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
...
我省略了其余的实现。现在这个类是将继承它的各种SubSystems的基类 - 一些继承的类需要使用UpdateGUI装饰器。
I've omitted the rest of the implementation. Now this class is a base class for various SubSystems that will inherit from it - some of the inherited classes will need to use the UpdateGUI decorator.
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
我再次省略了函数实现,因为它们不相关。
Once again I have omitted the function implementations as they are not relevant.
简而言之,问题是虽然我可以通过将其指定为SubSystem.UpdateGUI来从继承类访问基类中定义的装饰器,但最终我得到此TypeError尝试使用它:
In short the problem is that while I can access the decorator defined in the base class from the inherited class by specifiying it as SubSystem.UpdateGUI, I ultimately get this TypeError when trying to use it:
未绑定方法必须使用SubSystem实例作为第一个参数调用UpdateGUI()(改为获取函数实例)
这是因为我没有立即识别的方法将 self
参数传递给装饰器!
This is because I have no immediately identifiable way of passing the self
parameter to the decorator!
有没有办法做到这一点?或者我是否已达到Python中当前装饰器实现的限制?
Is there a way to do this? Or have I reached the limits of the current decorator implementation in Python?
推荐答案
您需要创建 UpdateGUI
a @classmethod
,并让你的包装
知道 self
。一个工作示例:
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
这篇关于作为基类一部分的Python装饰器不能用于装饰继承类中的成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!