[Python-ideas] Syntax for defining parametric decorators

Mike Graham mikegraham at gmail.com
Mon Jul 9 03:27:51 CEST 2012


On Sun, Jul 8, 2012 at 8:52 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Mike Graham wrote:
>>
>> A common stumbling block for new users is writing decorators that take
>> arguments. To create a decorator like
>
> I question that assertion. Have you spent much time on the tutor at python.org
> mailing list? I have, and I can say that decorators is not something that
> many new users there are concerned about *at all*, let alone decorators
> which take arguments.

I haven't, but I have spend considerable time helping people learn
Python. I'm a gold-badge Python answerer on Stack Overflow, an
op/regular on the #python IRC channel on freenode, and have taught
people in the meatosphere. Decorators is certainly a topic that
interests some people as they're still getting to know Python, and my
most recent Stack Overflow question was from someone confused about
some code using decorators and as recently as this morning I saw
someone on #python say they "wanted to learn about decorators" in the
abstract. In any event, I didn't mean _people completely brand new to
Python_ when I talked about people who were new.

> In my experience, most decorator factories (or factory-factories in general,
> not just for generators but any time you need to wrap a factory function in
> a closure) require at least one pre-processing step, and occasionally one or
> two post-processing steps as well:

In surveying actual decorator factories in the stdlib and my own code,
I didn't notice it to be the case there was any preprocessing inside
the outermost function. Maybe I just found the wrong ones.

> Concise, yes, but I disagree that it is self-explaining.
>
> I'm having a lot of difficulty in thinking of how I would explain it to even
> a moderately experienced user except by expanding it out to the explicit
> nested function form. I'm not sure I can even explain it to myself.
>
> What will happen when the user invariably writes something like this?
>
> def ordinary(a)(b):
>     return a + b
>
>
> My guess is that they will get a syntax error, but it will be a syntax error
> in the wrong place: instead of clearly flagging the error (a)(b) as invalid
> syntax, as you get now
>
> py> def ordinary(a)(b):
>   File "<stdin>", line 1
>     def ordinary(a)(b):
>                    ^
> SyntaxError: invalid syntax
>
>
> Instead, the user will get a less useful syntax error on the following line,
> where the compiler sees that the function def is not followed immediately by
> another function def.
>
>
> py> def ordinary(a)(b):
> ...     return a + b
>   File "<stdin>", line 1
>     return a + b
>     ^
> SyntaxError: invalid syntax
>
>
> So whatever clarity you (allegedly) gain when writing decorator factories,
> you lose when making an error.

I'm glad to get a different perspective here. It was evidently much
more self-explanatory to the folks I discussed this with before
posting.

I wouldn't have expected this to require the def to be immediately
followed by another def or for that to be the only (or most-common)
case. I would expect that to be proper syntax under this idea, and for
ordinary(3)(4) to be 7. I don't know if I said anything to suggest
that the syntax should be quite so specialcased, but I hope not.

Mike



More information about the Python-ideas mailing list