[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