[Python-ideas] An easier syntax for writing decorators (& similar things)?
Aaron Brady
castironpi at comcast.net
Wed Jan 23 10:44:25 CET 2008
> -----Original Message-----
> On 8 Oct 2007, at 10:57, Arnaud Delobelle wrote:
> >
> > On Mon, October 8, 2007 4:33 am, Adam Atlas wrote:
> >> When writing decorators especially when it's one that needs arguments
> >> other than the function to be wrapped, it often gets rather ugly...
> [...]
> > Whhy not create a (meta-)decorator to do this? Something like:
> [...]
Following up post from 10/8/07.
> To follow up on my untested suggestion, here's one that is tested:
>
> # This metadecorator hasn't changed
>
> def decorator_withargs(decf):
> def decorator(*args, **kwargs):
> def decorated(f):
> return decf(f, *args, **kwargs)
> return decorated
> return decorator
This is equivalent to:
(1)
decorator_withargs= partial( partial, prepartial )
, where prepartial is roughly the same as partial as you might expect:
(2)
1 def prepartial(func, *args, **keywords):
2 def newfunc(*fargs, **fkeywords):
3 newkeywords = keywords.copy()
4 newkeywords.update(fkeywords)
5 return func(*(fargs+ args), **newkeywords)
6 newfunc.func = func
7 newfunc.args = args
8 newfunc.keywords = keywords
9 return newfunc
Partial is the same outside of line 5:
(3)
5 return func(*(args + fargs), **newkeywords)
Results are the same:
-> f
1
f -> 2
2
Intriguing.
> # Here's how to use it to create a decorator
>
> @decorator_withargs
> def mydec(f, before='entering %s', after='%s returns %%s'):
> before = before % f.__name__
> after = after % f.__name__
> def decorated(*args, **kwargs):
> print before
> result = f(*args, **kwargs)
> print after % result
> return result
> return decorated
>
>
> # Now I can decorate a function with my new decorator
>
> @mydec(before='-> %s', after='%s -> %%s')
> def f(x):
> print x
> return x+1
>
>
> Then
>
> >>> f(1)
> -> f
> 1
> f -> 2
> 2
>
> --
> Arnaud
More information about the Python-ideas
mailing list