functools.wraps behaviour

Chris Angelico rosuav at gmail.com
Mon Sep 15 20:46:47 EDT 2014


On Tue, Sep 16, 2014 at 9:15 AM, ISE Development <isenntp at gmail.com> wrote:
>         @functools.wraps(func)
>         def wrapper(self):
>             func(self)
>         return wrapper
>
>     try:
>         k.method(1)
>     except Exception as e:
>         print('exception:',e)
>
> The output (Python 3.3) is:
>
> Klass.method: <function Klass.method at 0x7f2d7c454b00>
> k.method <bound method Klass.method of <__main__.Klass object at
> 0x7f2d7c4570d0>>
> exception: wrapper() takes 1 positional argument but 2 were given
>
> The first two lines are as expected, using the name of the decorated
> function. However, the exception uses the name of the decorating wrapper
> function.

In your wrapper, you're swallowing all arguments. That means you're
consciously rejecting them, and passing none on. If you want a wrapper
to let the wrapped function decide about arguments, try this:

    def decorator(func):
        @functools.wraps(func)
        def wrapper(self, *args, **kwargs):
            func(self, args, kwargs)
        return wrapper

With that change, the error message reports that it's method() that's
rejecting the args.

So yes, I'd say this is a feature; you can either let the wrapped
function make the decision, or you can have the wrapping function deal
with args.

ChrisA



More information about the Python-list mailing list