Problems with decorator with arguments to wrap class method
我正试图用包装特定类的方法的参数编写一个装饰器。我尝试了函数和类修饰器,但遇到了不同的错误。玩弄签名的争论没有帮助。
示例用法
1 2 3 4 5 6 7 8 9 10 11 | class X(object): def __init__(): self.a = True self.b ="" @my_deco([]) def xfunc(self, x, y): do stuff... foo = X() foo.xfunc() |
函数修饰器:
1 2 3 4 5 6 7 8 9 10 11 12 | 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个)
类修饰器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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 |