[Python-ideas] Syntax for defining parametric decorators

Devin Jeanpierre jeanpierreda at gmail.com
Mon Jul 9 03:55:09 CEST 2012


On Sun, Jul 8, 2012 at 9:46 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> However, the simplest possible complete definition of decorators is as follows:
>
> - a decorator expression (the bit after "@") on a def statement must
> produce a function decorator
> - a decorator expression on a class statement must produce a class decorator
> - a function decorator accepts a function and produces another object.
> This is typically another function (or even the original function for
> annotation and registration decorators), but may also be a different
> kind of object such as a descriptor (e.g. property, classmethod,
> staticmethod) or context manager (e.g. contextlib.contextmanager)
> - a class decorator is similar, but accepts a class rather than a function
> - a decorator factory is any callable that returns a decorator
> - function decorators are often written as functions that return a
> nested function (1 level of lexical nesting)
> - function decorator factories are often written as functions that
> return a function that returns a functions (2 levels of lexical
> nesting)

Mmm, this distinction of "kinds of decorators" is silly. The only
requirement for something to be a decorator is that it takes one
argument. The type of the argument could be anything.

def dumb_decorator(x):
    return x + 2

@dumb_decorator
@apply
def foo():
    return 5

> Creating a dedicated syntax for the special case of function decorator
> factories written to use lexical nesting makes the language as a whole
> *more* complicated rather than less. The only way to actually make
> them *simpler* would be to eliminate one or more of the bullet points
> from the above list, and that can't be done while retaining the
> current functionality.

Nothing about the OP's suggestion was specific to "function decorator
factories". Observe a class decorator factory:

def stupid_augmented_subclass_decorator(**kwargs)(cls):
    class MyClass(cls):
        pass
    MyClass.__dict__.update(**kwargs)
    return MyClass

-- Devin



More information about the Python-ideas mailing list