带参数的装饰器包裹类方法的问题
我正在尝试写一个带参数的装饰器,用来包装某个特定类的方法。我试过用函数装饰器和类装饰器,但都遇到了不同的错误。尝试调整参数的签名也没有帮助。
示例用法
class X(object):
def __init__():
self.a = True
self.b = ""
@my_deco([])
def xfunc(self, x, y):
do stuff...
foo = X()
foo.xfunc()
函数装饰器:
def my_deco(param1):
def wrapped(func):
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return func(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return param1
return wrapped_f
return wrapped
出现这个错误:TypeError: wrapped() 需要 1 个参数(给了 3 个)
类装饰器:
class my_deco(object):
def __init__(self, param1=False):
self.param1 = param1
def __call__(self, f):
@wraps(f)
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return f(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return self.param1
return wrapped_f
#
#def __get__(self, obj, objtype):
# """Support instance methods."""
# import functools
# return functools.partial(self.__call__, obj)
出现这个错误:TypeError: call() 需要 2 个参数(给了 3 个)
有没有什么线索可以帮助我解决这个问题?
1 个回答
1
在我尝试写出可以运行的代码作为示例时,我发现了自己的错误。可能是在写包装器的时候搞混了,导致我在让它工作时忽略了一个简单的错误。
下面是一个可以正常工作的例子。我犯的错误是没有给我正在测试的方法的装饰器传递参数,这就导致了异常。这解释了问题,因为装饰器是期待有一个参数的。
def my_deco(param1):
def wrapped(func):
def wrapped_f(self, *args, **kwargs):
try:
self.a = True
return func(self, *args, **kwargs)
except Exception as e:
self.b = str(e)
self.a = False
return param1
return wrapped_f
return wrapped
class Base(object):
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
self.a = False
self.b = ""
@my_deco([])
def xfunc(self, x, y):
return x + y
def ClassFactory(attr1, attr2, base=Base):
class NewClass(Base):
def __init__(self):
super(NewClass, self).__init__(attr1, attr2)
return NewClass
ChildClass = ClassFactory("foo", "bar")
child = ChildClass()
print child.xfunc(1, 2) # no exception
print child.xfunc('x', 2) # throws exception