问题
I got a pretty weird behaviour with the decorator library which is explained in the next code:
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)
The execution of this script prints:
$ python /tmp/test.py
Decorator: 1 (2,) {}
Home made decorator: 1 () {'b': 2}
'decorator' hides the kwargs inside the args, how can I solve this without using a "home made" decorator.
Thanks.
回答1:
Just because you call the function with b=2 does not make b a keyword argument; b is a positional argument in the original function. If there were no argument named b and you specified b=2, then b would become a keyword argument.
decorator's behavior is actually the most correct; the wrapper it generates has the same signature as funcion(), whereas the wrapper made by your "homemade" decorator does not have b as a named argument. The "homemade" wrapper "incorrectly" puts b in kwargs because the signature of myfuncion(), which makes it clear that b is not a keyword arg, is hidden from the caller.
Preserving the function signature is a feature, not a bug, in decorator.
来源:https://stackoverflow.com/questions/6700432/decorator-python-library-hide-the-kwargs-inside-args