装饰器Python库隐藏kwargs在args中
我遇到了一个很奇怪的情况,跟装饰器库有关,下面的代码解释了这个问题:
from decorator import decorator
@decorator
def wrap(f, a, *args, **kwargs):
print 'Decorator:', a, args, kwargs
return f(a, *args, **kwargs)
def mywrap(f):
def new_f(a, *args, **kwargs):
print 'Home made decorator:', a, args, kwargs
return f(a, *args, **kwargs)
return new_f
@wrap
def funcion(a, b, *args, **kwargs):
pass
@mywrap
def myfuncion(a, b, *args, **kwargs):
pass
funcion(1, b=2)
myfuncion(1, b=2)
运行这个脚本会打印出:
$ python /tmp/test.py
Decorator: 1 (2,) {}
Home made decorator: 1 () {'b': 2}
这个'decorator'把关键字参数(kwargs)藏在了位置参数(args)里面,我该怎么解决这个问题,而不想自己写一个装饰器呢?
谢谢。
1 个回答
6
你在调用这个函数的时候用 b=2
并不意味着 b
就是一个关键字参数;在原来的函数里,b
是一个位置参数。如果原本没有叫 b
的参数,而你指定了 b=2
,那么这时候 b
才会变成一个关键字参数。
decorator
的行为其实是最正确的;它生成的包装器和 funcion()
的参数列表是一样的,而你自己做的“自制”装饰器生成的包装器并没有把 b
作为一个命名参数。这个“自制”的包装器“错误地”把 b
放到了 kwargs
里,因为 myfuncion()
的参数列表清楚地表明 b
不是一个关键字参数,但这个信息对调用者是隐藏的。
保留函数的参数列表是一种特性,而不是错误,这在 decorator
中是很重要的。