我在使用类来装饰另一个类的方法时遇到了问题。代码如下
class decorator(object):
def __init__(self, func):
self.func = func
def __call__(self, *args):
return self.func(*args)
class test(object):
@decorator
def func(self, x, y):
print x, y
t = test()
t.func(1, 2)
显示此错误
TypeError:func()只需要3个参数(给定2个)。
如果使用
调用t.func(t, 1, 2)
然后它通过了。但是如果装饰器被带走,那么这条线将再次出现问题。
为什么会发生这种情况以及如何解决?
编辑:在装饰器中显示自我的代码的第二个版本。调用应该与test.func中的self不同
class decorator(object):
def __init__(self, func):
self.func = func
def __call__(self, *args):
return self.func(*args)
class test(object):
def __init__(self):
self.x = 1
self.y = 2
@decorator
def func(self):
print self
print self.x, self.y
t = test()
t.func()
这显示了同样的错误。但是
t.func(t)
有效但不理想。
答案 0 :(得分:2)
要作为方法工作,类中的对象需要实现the descriptor protocol的一部分。也就是说,它应该有一个__get__
方法,它返回一个可调用的对象,该对象已被“绑定”到查找该方法的实例。
这是使用包装函数实现这一目标的一种方法:
class decorator(object):
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
def wrapper(*args):
return self.func(instance, *args) # note, self here is the descriptor object
return wrapper
您可以从__get__
而不是函数返回其他类的实例,并使用该其他类的__call__
方法来实现包装器。如果您没有使用闭包,则需要将instance
显式传递给包装类(以及函数,因为self.func
将无法在描述符类之外工作)。