Function decorator having arguments is complicated
steve+comp.lang.python at pearwood.info
Mon Apr 27 09:36:15 CEST 2015
On Monday 27 April 2015 12:37, Makoto Kuwata wrote:
> I want to ask Python experts about function decorator which has arguments.
> I feel that function decorator having arguments is complicated,
> because three 'def' are nested:
> def multiply(n):
> def deco(func):
> def newfunc(*args, **kwargs):
> return n * func(*args, **kwargs)
> return newfunc
> return deco
Yes. But not that complicated -- it is only three levels, and the pattern is
- outer function takes arguments and returns a decorator;
- middle function is the decorator to be returned;
- inner function is the new function returned by the decorator.
So we start with a regular decorator:
def newfunc(*args, **kwargs):
return n * func(*args, **kwargs)
indent it one more level, and wrap it in a function:
# as above, indented one extra level
What's really tricky is a decorator which can *optionally* take arguments or
def function(): ...
# not the same as @decorate()
def function(): ...
> If function decorator notation could take arguments,
> decorator definition would be more simple:
Yes, but then we have to learn more syntax:
@decorate() # uses the default for multiply
could all be different.
Although I agree with you that writing a decorator factory is a bit
complicated, it is simple to break it up into individual sub-steps:
* I know how to write a function that adapts or wraps another
* I know how to write a decorator: write a function, indent it
one extra level, and wrap it in an outer function;
* I know how to write a decorator factory: write a decorator,
indent it one extra level, and wrap it in an outer function;
which could even be extended:
* I know how to write a decorator-factory factory: write a
decorator factory, indent it one extra level, and wrap it
in an outer function.
Saving one layer is not important enough to justify specialised syntax.
More information about the Python-list