问题
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