Factor in Anthony's text regarding the @ syntax and toss in a couple other
odd bits.
This commit is contained in:
parent
fe10049f8e
commit
8945c589a4
124
pep-0318.txt
124
pep-0318.txt
|
@ -51,7 +51,9 @@ replace::
|
|||
with an alternative that places the decoration in the function's
|
||||
declaration::
|
||||
|
||||
def foo(cls) using [synchronized(lock), classmethod]:
|
||||
@classmethod
|
||||
@synchronized(lock)
|
||||
def foo(cls):
|
||||
pass
|
||||
|
||||
Modifying classes in this fashion is also possible, though the
|
||||
|
@ -59,7 +61,8 @@ benefits are not as immediately apparent. Almost certainly, anything
|
|||
which could be done with class decorators could be done using
|
||||
metaclasses, but using metaclasses is sufficiently obscure that there
|
||||
is some attraction to having an easier way to make simple
|
||||
modifications to classes.
|
||||
modifications to classes. For Python 2.4, only function decorators
|
||||
are being added.
|
||||
|
||||
|
||||
Background
|
||||
|
@ -88,6 +91,26 @@ attributing the bracketed syntax to an earlier proposal on
|
|||
Class decorations seem like an obvious next step because class
|
||||
definition and function definition are syntactically similar.
|
||||
|
||||
The discussion continued on and off on python-dev from February 2002
|
||||
through July 2004. Many hundreds of posts were made, with people
|
||||
proposing many possible syntax variations. Guido took a list of
|
||||
proposals to `EuroPython 2004`_, where a discussion took place.
|
||||
Subsequent to this, he decided that for 2.4a2 we'd have the Java-style
|
||||
@decorator syntax. Barry Warsaw named this the 'pie-decorator'
|
||||
syntax, in honor of the Pie-thon Parrot shootout which was announced
|
||||
about the same time as the decorator syntax, and because the @ looks a
|
||||
little like a pie. Guido `outlined his case`_ on Python-dev,
|
||||
including `this piece`_ on the various rejected forms.
|
||||
|
||||
.. EuroPython 2004:
|
||||
http://www.python.org/doc/essays/ppt/euro2004/euro2004.pdf
|
||||
|
||||
.. outlined his case:
|
||||
http://mail.python.org/pipermail/python-dev/2004-August/authors.html
|
||||
|
||||
.. this piece:
|
||||
http://mail.python.org/pipermail/python-dev/2004-August/046672.html
|
||||
|
||||
|
||||
Design Goals
|
||||
============
|
||||
|
@ -95,7 +118,7 @@ Design Goals
|
|||
The new syntax should
|
||||
|
||||
* work for arbitrary wrappers, including user-defined callables and
|
||||
the existing builtins ``classmethod()`` and ``staticmethod``
|
||||
the existing builtins ``classmethod()`` and ``staticmethod()``
|
||||
|
||||
* work with multiple wrappers per definition
|
||||
|
||||
|
@ -119,23 +142,38 @@ The new syntax should
|
|||
.. _toy parser tools out there:
|
||||
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=mailman.1010809396.32158.python-list%40python.org
|
||||
|
||||
Andrew Kuchling has links to a bunch of the discussions about motivations
|
||||
`in his blog`_.
|
||||
|
||||
.. in his blog:
|
||||
http://www.amk.ca/diary/archives/cat_python.html#003255
|
||||
|
||||
Proposed Syntax
|
||||
===============
|
||||
|
||||
The currently proposed syntax for function decorators is::
|
||||
The current syntax for function decorators as implemented in Python
|
||||
2.4a2 is::
|
||||
|
||||
def func(arg1, arg2, ...) [dec1, dec2, ...]:
|
||||
@dec2
|
||||
@dec1
|
||||
def func(arg1, arg2, ...):
|
||||
pass
|
||||
|
||||
This is equivalent to::
|
||||
|
||||
def func(arg1, arg2, ...):
|
||||
pass
|
||||
func = dec2(dec1(func))
|
||||
|
||||
The decorators are near the declaration of the function's API but are
|
||||
clearly secondary. The square brackets make it possible to fairly
|
||||
easily break long lists of decorators across multiple lines.
|
||||
clearly secondary. The @ sign makes it clear that something new is
|
||||
going on here.
|
||||
|
||||
Class decorators are defined in an analogous fashion::
|
||||
The decorator statement is limited in what it can accept - arbitrary
|
||||
expressions will not work. Guido preferred this because of a `gut feeling`_
|
||||
|
||||
class MyClass(base1, base2) [dec1, dec2, ...]:
|
||||
pass
|
||||
.. gut feeling:
|
||||
http://mail.python.org/pipermail/python-dev/2004-August/046711.html
|
||||
|
||||
|
||||
Alternate Proposals
|
||||
|
@ -198,36 +236,73 @@ a `list of decorators`_ as a prefix to function definitions ::
|
|||
def foo(arg1, arg2, ...):
|
||||
pass
|
||||
|
||||
This appears to be his current favorite, but negative sentiment runs
|
||||
For a while this was Guido's preferred solution, but negative sentiment ran
|
||||
high, mostly because that syntax, though useless except for side
|
||||
effects of the list, is already legal and thus creates a special case.
|
||||
|
||||
.. _list of decorators:
|
||||
http://python.org/sf/926860
|
||||
|
||||
Another variant on the list syntax that was initially favored was::
|
||||
|
||||
Why [...]?
|
||||
----------
|
||||
def func(arg1, arg2, ...) [dec1, dec2]:
|
||||
pass
|
||||
|
||||
For syntax options which use a list-like syntax to specify the
|
||||
decorators a few alternatives have been proposed: ``[|...|]``,
|
||||
``*[...]*``, and ``<...>``. None have gained traction. The
|
||||
alternatives which involve square brackets only serve to make it
|
||||
Guido decided `he preferred`_ having the decorators on the line before
|
||||
the 'def', because it was felt that a long argument list would mean
|
||||
that the decorators would be 'hidden'
|
||||
|
||||
.. he preferred:
|
||||
http://mail.python.org/pipermail/python-dev/2004-March/043756.html
|
||||
|
||||
Phillip Eby and Jp Calderone both proposed variants that required
|
||||
no new syntax, but instead used some fairly advanced introspection
|
||||
to provide decorator-like behavoiur, but Guido was unimpressed by
|
||||
these, stating::
|
||||
|
||||
Using functions with "action-at-a-distance" through
|
||||
sys.settraceback may be okay for an obscure feature that can't be
|
||||
had any other way yet doesn't merit changes to the language, but
|
||||
that's not the situation for decorators. The widely held view
|
||||
here is that decorators need to be added as a syntactic feature to
|
||||
avoid the problems with the postfix notation used in 2.2 and 2.3.
|
||||
Decorators are slated to be an important new language feature and
|
||||
their design needs to be forward-looking, not constrained by what
|
||||
can be implemented in 2.3.
|
||||
|
||||
Why @?
|
||||
------
|
||||
|
||||
There is some history in Java using @ initially as a marker in
|
||||
`Javadoc comments`_ and later in ... mumble mumble ... The fact that
|
||||
@ was previously unused as a token in Python also means it's clear
|
||||
there is no possibility of such code being parsed by an earlier
|
||||
version of Python, leading to possibly subtle semantic bugs.
|
||||
|
||||
For syntax options which use a list-like syntax (no matter where it
|
||||
appears) to specify the decorators a few alternatives were proposed:
|
||||
``[|...|]``, ``*[...]*``, and ``<...>``. None gained much traction.
|
||||
The alternatives which involve square brackets only serve to make it
|
||||
obvious that the decorator construct is not a list. They do nothing
|
||||
to make parsing any easier. The '<...>' alternative presents parsing
|
||||
problems because '<' and '>' already parse as un-paired. They present
|
||||
a further parsing ambiguity because a right angle bracket might be a
|
||||
greater than symbol instead of a closer for the decorators.
|
||||
|
||||
.. Javadoc comments:
|
||||
http://java.sun.com/j2se/javadoc/writingdoccomments/
|
||||
|
||||
Current Implementation
|
||||
======================
|
||||
|
||||
Michael Hudson posted a `patch`_ at Starship, which implements the
|
||||
proposed syntax changes for both functions and classes and left-first
|
||||
application of decorators::
|
||||
Guido asked for a voluteer to implement his preferred syntax, and Mark
|
||||
Russell stepped up and posted a `patch`_ to SF. The syntax accepted
|
||||
for 2.4a2 is::
|
||||
|
||||
def func(arg1, arg2, ...) [dec1, dec2]:
|
||||
|
||||
@dec2
|
||||
@dec1
|
||||
def func(arg1, arg2, ...):
|
||||
pass
|
||||
|
||||
is equivalent to::
|
||||
|
@ -238,7 +313,12 @@ is equivalent to::
|
|||
|
||||
though without the intermediate creation of a variable named ``func``.
|
||||
|
||||
.. _patch: http://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
|
||||
.. _patch: http://www.python.org/sf/979728
|
||||
|
||||
A `previous patch`_ from Michael Hudson which implements the
|
||||
list-after-def syntax is also still kicking around.
|
||||
|
||||
.. _previous patch: http://starship.python.net/crew/mwh/hacks/meth-syntax-sugar-3.diff
|
||||
|
||||
|
||||
Examples
|
||||
|
|
Loading…
Reference in New Issue