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 pretty simple: - 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 deco(func): def newfunc(*args, **kwargs): return n * func(*args, **kwargs) return newfunc indent it one more level, and wrap it in a function: def multiply(n): # as above, indented one extra level What's really tricky is a decorator which can *optionally* take arguments or not: @decorator(x, y) def function(): ... # not the same as @decorate() @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 @decorate n @decorate(n) @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 function. * 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. -- Steve -- https://mail.python.org/mailman/listinfo/python-list