[Python-Dev] Re: PEP 318: Decorators last before colon
gmccaughan at synaptics-uk.com
Mon Apr 5 12:10:42 EDT 2004
On Monday 2004-04-05 at 15:42, Andrew Koenig wrote:
> Here's what I don't understand.
> I imagine that most of the time, when someone decorates a function with lots
> of attributes, there is at least the possibility of decorating more than one
> function with the same set of attributes.
> In such a case, doesn't it make sense to bind a variable to the attributes
> and use it instead?
> Attributes = [staticmethod, classmethod,
> def foo(bar, baz) Attributes:
> And doesn't this idea answer the objection that too many attributes after
> the parameter list make the definition hard to read?
It certainly answers that objection, but it has (so it seems to me)
other problems of its own; see below.
> For that matter, why do we need the brackets if there is only one attribute:
> def foo(bar, baz) staticmethod:
> I am suggesting that what comes between the ) and the : should be an
> expression, which must evaluate to either a callable or a sequence of
> callables. For that matter, why not allow a tuple expression without
> def foo(bar, baz) staticmethod, classmethod:
> Whatever sequence you put there, I think the semantics are clear: Before
> binding a name to the function, pass it to the callable or in turn to each
> element of the sequence.
The brackets serve multiple purposes.
- They make the decoration *look*, even to novice eyes, like
an annotation: "by the way, please make this a static method".
- They may possibly help the parser a little. (I'm showing
my ignorance here; I haven't really looked at the Python
parser at all.)
- They give a hint to the user that what goes in between them
may be a sequence, not just a single item.
- They ensure that all decorated definitions have a somewhat
Omitting them breaks all these things, especially if an arbitrary
expression is allowed there. And do we really want to allow
def foo(bar, baz) quux(wibble, spong):
That's not a hideous pathological case; it's what a simple
decoration using a parameterized decorator will look like
without the brackets. With good decorator names I suppose
it becomes somewhat comprehensible:
def foo(bar, baz) memoized(25):
but surely it's still much clearer when written as
def foo(bar, baz) [memoized(25)]:
or even (though I'm a little tempted to agree with whoever it was
that was wondering whether Guido has been abducted by aliens)
def foo(bar, baz):
We can keep the syntactic distinctiveness while still allowing
multiple decorators to be combined, by having a function
(a builtin, perhaps, but it's not hard to write) that
for d in decorators: f = d(f)
our_attributes = compose(staticmethod, classmethod,
def foo(bar, baz) [our_attributes]:
More information about the Python-Dev