我想装饰一个简单的方法,运行5次:
def do_5(f):
@wraps(f)
def wr(*a,**kw):
i = 0
while i < 5:
f(a,kw)
i += 1
return wr
class a(object):
@do_5
def f(self, x):
print x
但是,这只会使功能打印{}
,其中x实际上是1
使用ipdb,我看到self
是*a
的第一个,因此我尝试将包装器更改为
In [37]: def do_5(f):
...: @wraps(f)
...: def wr(*a,**kw):
...: self, other_args = a[0], a[1:]
...: i = 0
...: while i < 5:
...: f(self,other_args,kw)
...: i += 1
...: return wr
和
In [37]: def do_5(f):
...: @wraps(f)
...: def wr(*a,**kw):
...: self, other_args = a[0], a[1:]
...: i = 0
...: while i < 5:
...: self.f(other_args,kw)
...: i += 1
...: return wr
但得到:
RuntimeError: maximum recursion depth exceeded
和
TypeError: f() takes exactly 2 arguments (3 given)
分别
我该如何解决?
顺便说一句,我可以像@do_n(f,n)一样动态地修饰这个装饰器,并像这样装饰它(@do_n(100)
),而只需使用n
而不是5包装器?
答案 0 :(得分:4)
当您使用参数*a
和**kw
定义包装器时,a
是一个元组,kw
是一个字典。函数定义中的*
和**
是在调用函数时将参数收集到两个参数中的信号。您要将这两个对象传递给f
,而不是其中包含参数 containing 。您需要在对包装函数的调用中将其解压缩。在通话中,*
和**
解包所附的名称。
def do_5(f):
@wraps(f)
def wr(*a,**kw):
i = 0
while i < 5:
f(*a, **kw)
i += 1
return wr
现在,a().f(3)
将输出
3
3
3
3
3
符合预期。
答案 1 :(得分:0)
您需要按原样转发数据,f(*a,**kw)
,a是一个元组,kw是字典。
from functools import wraps
def do_5(f):
@wraps(f)
def wr(*a,**kw):
i = 0
while i < 5:
f(*a,**kw)
i += 1
return wr
class a(object):
@do_5
def f(self, x):
print x
b = a()
b.f(1)