Python 使用MethodType将方法从一个实例动态添加到另一个实例
我试图用新方法装饰类实例。但是,如果装饰者自己添加了一个方法,它会给我一个错误Python 使用MethodType将方法从一个实例动态添加到另一个实例,python,python-3.x,Python,Python 3.x,我试图用新方法装饰类实例。但是,如果装饰者自己添加了一个方法,它会给我一个错误 TypeError: myMethod() takes 1 positional argument but 2 were given 举一个简单的例子,假设我有一个不能修改的类MyElement,还有一个装饰器将一个方法从自身添加到MyElement的实例中 class MyElement(object): def __init(self): self._name = "MyElement"
TypeError: myMethod() takes 1 positional argument but 2 were given
举一个简单的例子,假设我有一个不能修改的类MyElement,还有一个装饰器将一个方法从自身添加到MyElement的实例中
class MyElement(object):
def __init(self):
self._name = "MyElement"
class Decorator(object):
def myMethod(self):
print(self._name)
def decorate(self, element):
element.myMethod = MethodType(self.myMethod, element)
if __name__ == '__main__':
d = Decorator()
p = MyElement()
d.decorate(p)
p.myMethod()
这给了我上面的错误。尽管我把装饰改成这样,但它仍然有效:
def decorate(self, element):
element.myMethod = MethodType(self.myMethod.__func__, element)
有人能解释一下MethodType到底在做什么吗?为什么必须使用func标志?您正在使用
MethodType
将您的装饰程序的myMethod
方法绑定到另一个对象。这不起作用,因为当您使用self.myMethod
访问它时,您已经得到了一个绑定方法。第一个绑定将Decorator
对象作为self
传递,第二个绑定在尝试将MyElement
实例作为第二个参数传递时导致异常
有几种方法可以解决这个问题。目前还不清楚哪种方法最适合您,因为您的myMethod
示例对self
没有任何作用
一个选项是通过Decorator
类访问myMethod
,而不是通过self
。这意味着它将被解除绑定(当然,直到您将其包装在MethodType
中)。在此版本中,myMethod
中看到的self
值将是MyElement
实例,而不是Decorator
(阅读代码的人可能会感到惊讶)。在Python2中,未绑定方法有一个特殊的检查,即self
是正确的类型,因此这不起作用
def decorate(self, element):
element.myMethod = MethodType(Decorator.myMethod, element)
另一个选项是将使用self.myMethod
获得的绑定方法保存为元素
上的变量,而不尝试再次绑定它。使用这种方法,self
仍然是decorator对象,即使该方法是通过MyElement
对象调用的
def decorate(self, element):
element.myMethod = self.myMethod
最后一个选项是保持decoration
方法不变,但在myMethod
中添加一个额外的参数。这将允许传入Decorator
实例(作为self
)和MyElement
实例:
def myMethod(self, element):
print("{} is decorated by {}".format(element, self))
谢谢你非常准确的回答,现在我理解了MethodTypeelement.myMethod=Decorator.myMethod
适合我。