我使用装饰器库得到了一个非常奇怪的行为,这将在下一个代码中解释:
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'隐藏了args中的kwargs,如何在不使用“自制”装饰器的情况下解决这个问题。
感谢。
答案 0 :(得分:5)
仅仅因为你调用,b=2
的函数不会使b
成为关键字参数; b
是原始函数中的位置参数。如果没有名为b
的参数并且您指定了b=2
,那么则 b
将成为关键字参数。
decorator
的行为实际上是最正确的;它生成的包装器与funcion()
具有相同的签名,而由“自制”装饰器创建的包装器没有b
作为命名参数。 “自制”包装器“错误地”将b
放入kwargs
,因为myfuncion()
的签名(表明b
不是关键字arg)隐藏在呼叫者。
保留功能签名是decorator
中的一项功能,而不是错误。