Decorators not worth the effort

Terry Reedy tjreedy at udel.edu
Fri Sep 14 16:29:25 EDT 2012


On 9/13/2012 10:12 PM, Cameron Simpson wrote:
> On 13Sep2012 18:58, alex23 <wuwei23 at gmail.com> wrote:
> | On Sep 14, 3:54 am, Jean-Michel Pichavant <jeanmic... at sequans.com>
> | wrote:
> | > I don't like decorators, I think they're not worth the mental effort.
> |
> | Because passing a function to a function is a huge cognitive burden?

For parameterized decorators, there is extra cognitive burden. See below.


> It is for me when I'm _writing_ the decorator:-) But if I get it right
> and name it well I find it dramaticly _decreases_ the cognitive burden
> of the code using the decorator...

For a simple, unparameterized wrapper, the difficulty is entirely in the 
wrapper maker. It must define the final wrapper as a nested function and 
return it*. It is irrelevant whether the wrapper maker is used with 
pre-def decorator syntax or with an explicit post-def call.

*I am here ignoring the option of a class with __call__ method.

For a parameterized wrapper, using decorator syntax requires passing the 
parameter(s) first and the function to be wrapped later. This requires 
currying the wrapper maker with double nesting. The nesting order may 
seem inside-out to some. For most people, this is extra work compared to 
writing a wrapper that accepts the function and parameters together and 
only has a single level of nesting.

In other words

def make_wrapper(func, param):
     def wrapper(*args, **kwds):
         for i in range(param):
             func(*args, **kwds)
     return wrapper

def f(x): print(x)
f = make_wrapper(f, 2)
f('simple')

# is simpler, at least for some people, than the following
# which does essentially the same thing.

def make_outer(param):
     def make_inner(func):
         def wrapper(*args, **kwds):
             for i in range(param):
                 func(*args, **kwds)
         return wrapper
     return make_inner

@make_outer(2)
def f(x): print(x)
f('complex')

Is the gain of not repeating the wrapped function name twice in the 
post-def wrapping call, and the gain of knowing the function will be 
wrapped before reading the def, worth the pain of currying the wrapper 
maker?

-- 
Terry Jan Reedy




More information about the Python-list mailing list