Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

decorator python library hide the kwargs inside args

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.

like image 297
Jorge E. Cardona Avatar asked Sep 12 '26 20:09

Jorge E. Cardona


1 Answers

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.

like image 60
kindall Avatar answered Sep 14 '26 11:09

kindall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!