Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #89438 > unrolled thread
| Started by | Makoto Kuwata <kwa@kuwata-lab.com> |
|---|---|
| First post | 2015-04-27 11:37 +0900 |
| Last post | 2015-04-29 21:22 +1200 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.python
Function decorator having arguments is complicated Makoto Kuwata <kwa@kuwata-lab.com> - 2015-04-27 11:37 +0900
Re: Function decorator having arguments is complicated Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-04-27 17:36 +1000
Re: Function decorator having arguments is complicated Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2015-04-29 21:22 +1200
| From | Makoto Kuwata <kwa@kuwata-lab.com> |
|---|---|
| Date | 2015-04-27 11:37 +0900 |
| Subject | Function decorator having arguments is complicated |
| Message-ID | <mailman.31.1430102277.3680.python-list@python.org> |
[Multipart message — attachments visible in raw view] — view raw
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
@multiply(4)
def f1(x, y):
return x+y
print(f1(2, 3)) #=> 20 (= 4 * (2+3))
If function decorator notation could take arguments,
decorator definition would be more simple:
def multiply(func, n):
def newfunc(*args, **kwargs):
return n * func(*args, **kwargs)
return newfunc
@multiply 4 # ex: @decorator arg1, arg2, arg3
def f1(x, y):
return x+y
How do you think about this idea?
--
regards,
makoto kuwata
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-04-27 17:36 +1000 |
| Message-ID | <553de6f1$0$12905$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #89438 |
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
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2015-04-29 21:22 +1200 |
| Message-ID | <cqbm6bFdooeU1@mid.individual.net> |
| In reply to | #89450 |
> On Monday 27 April 2015 12:37, Makoto Kuwata wrote:
>
>> def multiply(n):
>> def deco(func):
>> def newfunc(*args, **kwargs):
>> return n * func(*args, **kwargs)
>> return newfunc
>> return deco
I'd like to be able to write that as
def multiply(n)(func)(*args, **kwargs):
return n * func(*args, **kwargs)
--
Greg
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web