ding dong the witch is dead. or rather, the decorator discussion is.
updating the pep. (I'm not sure if the "Community Concensus" section should be trimmed down radically now - it's a lot of words for a rejected form, and the case for the form is still available on the web and in the mailing list archives... opinions, anyone?)
This commit is contained in:
parent
1373ea5150
commit
b13a4cc305
361
pep-0318.txt
361
pep-0318.txt
|
@ -8,49 +8,49 @@ Type: Standards Track
|
|||
Content-Type: text/x-rst
|
||||
Created: 05-Jun-2003
|
||||
Python-Version: 2.4
|
||||
Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004
|
||||
Post-History: 09-Jun-2003, 10-Jun-2003, 27-Feb-2004, 23-Mar-2004, 30-Aug-2004,
|
||||
2-Sep-2004
|
||||
|
||||
|
||||
WarningWarningWarning
|
||||
=====================
|
||||
|
||||
The final decision on the syntax for 2.4a3 is not yet made. This will
|
||||
be done before 2.4a3, and this document will be updated to match.
|
||||
Note also that this document does not attempt to cover the huge number
|
||||
of potential alternative syntaxes, nor is it an attempt to
|
||||
exhaustively list all the positives and negatives of each form.
|
||||
This document is meant to describe the decorator syntax and the
|
||||
process that resulted in the decisions that were made. It does not
|
||||
attempt to cover the huge number of potential alternative syntaxes,
|
||||
nor is it an attempt to exhaustively list all the positives and
|
||||
negatives of each form.
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
The current method for transforming functions and methods (for
|
||||
instance, declaring them as a class or static method) is awkward and
|
||||
can lead to code that is difficult to understand. Ideally, these
|
||||
transformations should be made at the same point in the code where the
|
||||
declaration itself is made. This PEP introduces new syntax for
|
||||
transformations of a function or method declaration.
|
||||
The current method for transforming functions and methods (for instance,
|
||||
declaring them as a class or static method) is awkward and can lead to
|
||||
code that is difficult to understand. Ideally, these transformations
|
||||
should be made at the same point in the code where the declaration
|
||||
itself is made. This PEP introduces new syntax for transformations of a
|
||||
function or method declaration.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
The current method of applying a transformation to a function or
|
||||
method places the actual translation after the function body. For
|
||||
large functions this separates a key component of the function's
|
||||
behavior from the definition of the rest of the function's external
|
||||
interface. For example::
|
||||
The current method of applying a transformation to a function or method
|
||||
places the actual translation after the function body. For large
|
||||
functions this separates a key component of the function's behavior from
|
||||
the definition of the rest of the function's external interface. For
|
||||
example::
|
||||
|
||||
def foo(self):
|
||||
perform method operation
|
||||
foo = classmethod(foo)
|
||||
|
||||
This becomes less readable with longer methods. It also seems less
|
||||
than pythonic to name the function three times for what is
|
||||
conceptually a single declaration. A solution to this problem is to
|
||||
move the transformation of the method closer to the method's own
|
||||
declaration. While the new syntax is not yet final, the intent is to
|
||||
replace::
|
||||
than pythonic to name the function three times for what is conceptually
|
||||
a single declaration. A solution to this problem is to move the
|
||||
transformation of the method closer to the method's own declaration.
|
||||
While the new syntax is not yet final, the intent is to replace::
|
||||
|
||||
def foo(cls):
|
||||
pass
|
||||
|
@ -65,41 +65,39 @@ declaration::
|
|||
def foo(cls):
|
||||
pass
|
||||
|
||||
Modifying classes in this fashion is also possible, though the
|
||||
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. For Python 2.4, only function/method
|
||||
decorators are being added.
|
||||
Modifying classes in this fashion is also possible, though the 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. For
|
||||
Python 2.4, only function/method decorators are being added.
|
||||
|
||||
|
||||
Why Is This So Hard?
|
||||
--------------------
|
||||
|
||||
Two decorators (``classmethod()`` and ``staticmethod()``) have
|
||||
been available in Python since version 2.2. It's been assumed since
|
||||
Two decorators (``classmethod()`` and ``staticmethod()``) have been
|
||||
available in Python since version 2.2. It's been assumed since
|
||||
approximately that time that some syntactic support for them would
|
||||
eventually be added to the language. Given this assumption, one might
|
||||
wonder why it's been so difficult to arrive at a consensus.
|
||||
Discussions have raged off-and-on at times in both comp.lang.python
|
||||
and the python-dev mailing list about how best to implement function
|
||||
decorators. There is no one clear reason why this should be so, but a
|
||||
few problems seem to be most problematic.
|
||||
wonder why it's been so difficult to arrive at a consensus. Discussions
|
||||
have raged off-and-on at times in both comp.lang.python and the
|
||||
python-dev mailing list about how best to implement function decorators.
|
||||
There is no one clear reason why this should be so, but a few problems
|
||||
seem to be most problematic.
|
||||
|
||||
* Disagreement about where the "declaration of intent" belongs.
|
||||
Almost everyone agrees that decorating/transforming a function at
|
||||
the end of its definition is suboptimal. Beyond that there seems to
|
||||
be no clear consensus where to place this information.
|
||||
Almost everyone agrees that decorating/transforming a function at the
|
||||
end of its definition is suboptimal. Beyond that there seems to be no
|
||||
clear consensus where to place this information.
|
||||
|
||||
* Syntactic constraints. Python is a syntactically simple language
|
||||
with fairly strong constraints on what can and can't be done without
|
||||
"messing things up" (both visually and with regards to the language
|
||||
parser). There's no obvious way to structure this information so
|
||||
that people new to the concept will think, "Oh yeah, I know what
|
||||
you're doing." The best that seems possible is to keep new users
|
||||
from creating a wildly incorrect mental model of what the syntax
|
||||
means.
|
||||
you're doing." The best that seems possible is to keep new users from
|
||||
creating a wildly incorrect mental model of what the syntax means.
|
||||
|
||||
* Overall unfamiliarity with the concept. For people who have a
|
||||
passing acquaintance with algebra (or even basic arithmetic) or have
|
||||
|
@ -109,7 +107,7 @@ few problems seem to be most problematic.
|
|||
strong preexisting meme that captures the concept.
|
||||
|
||||
* Syntax discussions in general appear to cause more contention than
|
||||
almost anything else. Readers are pointed to the ternary operator
|
||||
almost anything else. Readers are pointed to the ternary operator
|
||||
discussions that were associated with PEP 308 for another example of
|
||||
this.
|
||||
|
||||
|
@ -117,12 +115,12 @@ few problems seem to be most problematic.
|
|||
Background
|
||||
==========
|
||||
|
||||
There is general agreement that syntactic support is desirable to the
|
||||
current state of affairs. Guido mentioned `syntactic support for
|
||||
decorators`_ in his DevDay keynote presentation at the `10th Python
|
||||
Conference`_, though `he later said`_ it was only one of several
|
||||
extensions he proposed there "semi-jokingly". `Michael Hudson raised
|
||||
the topic`_ on ``python-dev`` shortly after the conference,
|
||||
There is general agreement that syntactic support is desirable to
|
||||
the current state of affairs. Guido mentioned `syntactic support
|
||||
for decorators`_ in his DevDay keynote presentation at the `10th
|
||||
Python Conference`_, though `he later said`_ it was only one of
|
||||
several extensions he proposed there "semi-jokingly". `Michael Hudson
|
||||
raised the topic`_ on ``python-dev`` shortly after the conference,
|
||||
attributing the initial bracketed syntax to an earlier proposal on
|
||||
``comp.lang.python`` by `Gareth McCaughan`_.
|
||||
|
||||
|
@ -138,18 +136,21 @@ attributing the initial bracketed syntax to an earlier proposal on
|
|||
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=slrna40k88.2h9o.Gareth.McCaughan%40g.local
|
||||
|
||||
Class decorations seem like an obvious next step because class
|
||||
definition and function definition are syntactically similar.
|
||||
definition and function definition are syntactically similar,
|
||||
however Guido remains unconvinced, and class decorators will almost
|
||||
certainly not be in Python 2.4.
|
||||
|
||||
The discussion continued on and off on python-dev from February 2002
|
||||
through July 2004. Hundreds and 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.
|
||||
The discussion continued on and off on python-dev from February
|
||||
2002 through July 2004. Hundreds and 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 we'd have the `Java-style`_
|
||||
@decorator syntax, and this appeared for the first time in 2.4a2.
|
||||
Barry Warsaw named this the 'pie-decorator' syntax, in honor of the
|
||||
Pie-thon Parrot shootout which was occured around 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 some of the (many) rejected forms.
|
||||
|
||||
.. _EuroPython 2004:
|
||||
http://www.python.org/doc/essays/ppt/euro2004/euro2004.pdf
|
||||
|
@ -199,8 +200,8 @@ The new syntax should
|
|||
frequently
|
||||
|
||||
* not make it more difficult to scan through code quickly. It should
|
||||
still be easy to search for all definitions, a particular
|
||||
definition, or the arguments that a function accepts
|
||||
still be easy to search for all definitions, a particular definition,
|
||||
or the arguments that a function accepts
|
||||
|
||||
* not needlessly complicate secondary support tools such as
|
||||
language-sensitive editors and other "`toy parser tools out
|
||||
|
@ -208,8 +209,8 @@ The new syntax should
|
|||
|
||||
* allow future compilers to optimize for decorators. With the hope of
|
||||
a JIT compiler for Python coming into existence at some point this
|
||||
tends to require the syntax for decorators to come before the
|
||||
function definition
|
||||
tends to require the syntax for decorators to come before the function
|
||||
definition
|
||||
|
||||
* move from the end of the function, where it's currently hidden, to
|
||||
the front where it is more `in your face`_
|
||||
|
@ -246,8 +247,8 @@ This is equivalent to::
|
|||
func = dec2(dec1(func))
|
||||
|
||||
without the intermediate assignment to the variable ``func``. The
|
||||
decorators are near the function declaration. The @ sign makes it
|
||||
clear that something new is going on here.
|
||||
decorators are near the function declaration. The @ sign makes it clear
|
||||
that something new is going on here.
|
||||
|
||||
The decorator statement is limited in what it can accept -- arbitrary
|
||||
expressions will not work. Guido preferred this because of a `gut
|
||||
|
@ -278,8 +279,8 @@ Decorator Location
|
|||
The first syntax point is the location of the decorators. For the
|
||||
following examples, we use the @syntax used in 2.4a2.
|
||||
|
||||
Decorators before the def statement are the first alternative,
|
||||
and the syntax used in 2.4a2::
|
||||
Decorators before the def statement are the first alternative, and the
|
||||
syntax used in 2.4a2::
|
||||
|
||||
@classmethod
|
||||
def foo(arg1,arg2):
|
||||
|
@ -290,36 +291,36 @@ and the syntax used in 2.4a2::
|
|||
def bar(low,high):
|
||||
pass
|
||||
|
||||
There have been a number of objections raised to this location --
|
||||
the primary one is that it's the first real Python case where a
|
||||
line of code has a result on a following line. The syntax that
|
||||
will be in 2.4a3 will also require one decorator per line (in a2,
|
||||
multiple decorators can be specified on the same line).
|
||||
There have been a number of objections raised to this location -- the
|
||||
primary one is that it's the first real Python case where a line of code
|
||||
has a result on a following line. The syntax available for in 2.4a3
|
||||
requires one decorator per line (in a2, multiple decorators could be
|
||||
specified on the same line).
|
||||
|
||||
People also complained that the syntax got unworldly quickly when
|
||||
multiple decorators were used. The point was made, though, that the
|
||||
chances of a large number of decorators being used on a single function
|
||||
were small and thus this was not a large worry.
|
||||
|
||||
Some of the advantages of this form are that the decorators live
|
||||
outside the method body -- they are obviously executed at the time
|
||||
the function is defined.
|
||||
Some of the advantages of this form are that the decorators live outside
|
||||
the method body -- they are obviously executed at the time the function
|
||||
is defined.
|
||||
|
||||
Another advantage is that being prefix to the function definition fit the
|
||||
idea of knowing about a change to the semantics of the code before the
|
||||
code itself, thus knowing how to interpret the code's semantics
|
||||
Another advantage is that being prefix to the function definition fit
|
||||
the idea of knowing about a change to the semantics of the code before
|
||||
the code itself, thus knowing how to interpret the code's semantics
|
||||
properly without having to go back and change your initial perceptions
|
||||
if the syntax did not come before the function definition.
|
||||
|
||||
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'
|
||||
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
|
||||
|
||||
The second form is the decorators between the def and the function
|
||||
name, or the function name and the argument list::
|
||||
The second form is the decorators between the def and the function name,
|
||||
or the function name and the argument list::
|
||||
|
||||
def @classmethod foo(arg1,arg2):
|
||||
pass
|
||||
|
@ -336,12 +337,12 @@ name, or the function name and the argument list::
|
|||
There are a couple of objections to this form. The first is that it
|
||||
breaks easily 'greppability' of the source -- you can no longer search
|
||||
for 'def foo(' and find the definition of the function. The second,
|
||||
more serious, objection is that in the case of multiple decorators,
|
||||
the syntax would be extremely unwieldy.
|
||||
more serious, objection is that in the case of multiple decorators, the
|
||||
syntax would be extremely unwieldy.
|
||||
|
||||
The next form, which has had a number of strong proponents, is to
|
||||
have the decorators between the argument list and the trailing ``:``
|
||||
in the 'def' line::
|
||||
The next form, which has had a number of strong proponents, is to have
|
||||
the decorators between the argument list and the trailing ``:`` in the
|
||||
'def' line::
|
||||
|
||||
def foo(arg1,arg2) @classmethod:
|
||||
pass
|
||||
|
@ -349,8 +350,8 @@ in the 'def' line::
|
|||
def bar(low,high) @accepts(int,int),@returns(float):
|
||||
pass
|
||||
|
||||
Guido `summarized the arguments`_ against this form (many of which
|
||||
also apply to the previous form) as:
|
||||
Guido `summarized the arguments`_ against this form (many of which also
|
||||
apply to the previous form) as:
|
||||
|
||||
- it hides crucial information (e.g. that it is a static method)
|
||||
after the signature, where it is easily missed
|
||||
|
@ -364,9 +365,8 @@ also apply to the previous form) as:
|
|||
.. _summarized the arguments:
|
||||
http://mail.python.org/pipermail/python-dev/2004-August/047112.html
|
||||
|
||||
The next form is that the decorator syntax go inside the method
|
||||
body at the start, in the same place that docstrings currently
|
||||
live:
|
||||
The next form is that the decorator syntax go inside the method body at
|
||||
the start, in the same place that docstrings currently live:
|
||||
|
||||
def foo(arg1,arg2):
|
||||
@classmethod
|
||||
|
@ -377,16 +377,16 @@ live:
|
|||
@returns(float)
|
||||
pass
|
||||
|
||||
The primary objection to this form is that it requires "peeking
|
||||
inside" the method body to determine the decorators. In addition,
|
||||
even though the code is inside the method body, it is not executed
|
||||
when the method is run. Guido felt that docstrings were not a good
|
||||
counter-example, and that it was quite possible that a 'docstring'
|
||||
decorator could help move the docstring to outside the function body.
|
||||
The primary objection to this form is that it requires "peeking inside"
|
||||
the method body to determine the decorators. In addition, even though
|
||||
the code is inside the method body, it is not executed when the method
|
||||
is run. Guido felt that docstrings were not a good counter-example, and
|
||||
that it was quite possible that a 'docstring' decorator could help move
|
||||
the docstring to outside the function body.
|
||||
|
||||
The final form is a new block that encloses the method's code. For
|
||||
this example, we'll use a 'decorate' keyword, as it makes no sense
|
||||
with the @syntax. ::
|
||||
The final form is a new block that encloses the method's code. For this
|
||||
example, we'll use a 'decorate' keyword, as it makes no sense with the
|
||||
@syntax. ::
|
||||
|
||||
decorate:
|
||||
classmethod
|
||||
|
@ -400,8 +400,8 @@ with the @syntax. ::
|
|||
pass
|
||||
|
||||
This form would result in inconsistent indentation for decorated and
|
||||
undecorated methods. In addition, a decorated method's body would
|
||||
start three indent levels in.
|
||||
undecorated methods. In addition, a decorated method's body would start
|
||||
three indent levels in.
|
||||
|
||||
|
||||
Syntax forms
|
||||
|
@ -420,7 +420,7 @@ Syntax forms
|
|||
|
||||
The major objections against this syntax are that the @ symbol is
|
||||
not currently used in Python (and is used in both IPython and Leo),
|
||||
and that the @ symbol is not meaningful. Another objection is that
|
||||
and that the @ symbol is not meaningful. Another objection is that
|
||||
this "wastes" a currently unused character (from a limited set) on
|
||||
something that is not perceived as a major use.
|
||||
|
||||
|
@ -437,8 +437,8 @@ Syntax forms
|
|||
|
||||
This is a variant on the @decorator syntax -- it has the advantage
|
||||
that it does not break IPython and Leo. Its major disadvantage
|
||||
compared to the @syntax is that the | symbol looks like both a
|
||||
capital I and a lowercase l.
|
||||
compared to the @syntax is that the | symbol looks like both a capital
|
||||
I and a lowercase l.
|
||||
|
||||
* list syntax::
|
||||
|
||||
|
@ -474,28 +474,29 @@ Syntax forms
|
|||
|
||||
* ``decorate()``
|
||||
|
||||
The ``decorate()`` proposal was that no new syntax be implemented --
|
||||
instead a magic function that used introspection to manipulate the
|
||||
following function. Both Jp Calderone and Philip Eby produced
|
||||
The ``decorate()`` proposal was that no new syntax be implemented
|
||||
-- instead a magic function that used introspection to manipulate
|
||||
the following function. Both Jp Calderone and Philip Eby produced
|
||||
implementations of functions that did this. Guido was pretty firmly
|
||||
against this -- with no new syntax, the magicness of a function like
|
||||
this is extremely high:
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
* _`new keyword (and block)`
|
||||
|
||||
This idea was the consensus alternate from comp.lang.python. Robert
|
||||
Brewer wrote up a detailed `J2 proposal`_ document outlining the
|
||||
arguments in favor of this. The issues with this form are:
|
||||
This idea was the consensus alternate from comp.lang.python (more
|
||||
on this in `Community Consensus`_ below.) Robert Brewer wrote up a
|
||||
detailed `J2 proposal`_ document outlining the arguments in favor of
|
||||
this form. The initial issues with this form are:
|
||||
|
||||
- It requires a new keyword, and therefore a ``from __future__
|
||||
import decorators`` statement.
|
||||
|
@ -508,12 +509,39 @@ Syntax forms
|
|||
code block, but isn't. Attempts to use statements in this block
|
||||
will cause a syntax error, which may confuse users.
|
||||
|
||||
See `Community Consensus`_ below.
|
||||
A few days later, Guido `rejected the proposal`_ on two main grounds,
|
||||
firstly:
|
||||
|
||||
... the syntactic form of an indented block strongly
|
||||
suggests that its contents should be a sequence of statements, but
|
||||
in fact it is not -- only expressions are allowed, and there is an
|
||||
implicit "collecting" of these expressions going on until they can
|
||||
be applied to the subsequent function definition. ...
|
||||
|
||||
and secondly:
|
||||
|
||||
... the keyword starting the line that heads a block
|
||||
draws a lot of attention to it. This is true for "if", "while",
|
||||
"for", "try", "def" and "class". But the "using" keyword (or any
|
||||
other keyword in its place) doesn't deserve that attention; the
|
||||
emphasis should be on the decorator or decorators inside the suite,
|
||||
since those are the important modifiers to the function definition
|
||||
that follows. ...
|
||||
|
||||
Readers are invited to read `the full response`_.
|
||||
|
||||
.. _J2 proposal:
|
||||
http://www.aminus.org/rbre/python/pydec.html
|
||||
|
||||
There are plenty of other variants and proposals on `the wiki page`_.
|
||||
.. _rejected the proposal:
|
||||
http://mail.python.org/pipermail/python-dev/2004-September/048518.html
|
||||
|
||||
.. _the full response:
|
||||
http://mail.python.org/pipermail/python-dev/2004-September/048518.html
|
||||
|
||||
* Other forms
|
||||
|
||||
There are plenty of other variants and proposals on `the wiki page`_.
|
||||
|
||||
.. _the wiki page:
|
||||
http://www.python.org/moin/PythonDecorators
|
||||
|
@ -522,18 +550,18 @@ There are plenty of other variants and proposals on `the wiki page`_.
|
|||
Why @?
|
||||
------
|
||||
|
||||
There is some history in Java using @ initially as a marker in
|
||||
`Javadoc comments`_ and later in Java 1.5 for `annotations`_, which
|
||||
are similar to Python decorators. 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. It also means that ambiguity
|
||||
of what is a decorator and what isn't is removed. of That said, @ is
|
||||
still a fairly arbitrary choice. Some have suggested using | instead.
|
||||
There is some history in Java using @ initially as a marker in `Javadoc
|
||||
comments`_ and later in Java 1.5 for `annotations`_, which are similar
|
||||
to Python decorators. 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. It also means that ambiguity of what is a decorator
|
||||
and what isn't is removed. of That said, @ is still a fairly arbitrary
|
||||
choice. Some have suggested using | instead.
|
||||
|
||||
For syntax options which use a list-like syntax (no matter where it
|
||||
appears) to specify the decorators a few alternatives were proposed:
|
||||
``[|...|]``, ``*[...]*``, and ``<...>``.
|
||||
``[|...|]``, ``*[...]*``, and ``<...>``.
|
||||
|
||||
.. _Javadoc comments:
|
||||
http://java.sun.com/j2se/javadoc/writingdoccomments/
|
||||
|
@ -545,8 +573,8 @@ Current Implementation, History
|
|||
===============================
|
||||
|
||||
Guido asked for a volunteer to implement his preferred syntax, and Mark
|
||||
Russell stepped up and posted a `patch`_ to SF. The syntax accepted
|
||||
for 2.4a2 is::
|
||||
Russell stepped up and posted a `patch`_ to SF. This new syntax was
|
||||
available in 2.4a2. ::
|
||||
|
||||
@dec2
|
||||
@dec1
|
||||
|
@ -561,6 +589,10 @@ This is equivalent to::
|
|||
|
||||
though without the intermediate creation of a variable named ``func``.
|
||||
|
||||
The version implemented in 2.4a2 allowed multiple ``@decorator`` clauses
|
||||
on a single line. In 2.4a3, this was tightened up to only allowing one
|
||||
decorator per line.
|
||||
|
||||
A `previous patch`_ from Michael Hudson which implements the
|
||||
list-after-def syntax is also still kicking around.
|
||||
|
||||
|
@ -572,19 +604,44 @@ stated that he'd re-examine a community proposal, if the community
|
|||
could come up with a community consensus, a decent proposal, and an
|
||||
implementation. After an amazing number of posts, collecting a vast
|
||||
number of alternatives in the `Python wiki`_, a community consensus
|
||||
emerged (below). As at time of writing, we're waiting for Guido's
|
||||
decision.
|
||||
emerged (below). Guido `subsequently rejected`_ this alternate form,
|
||||
but added:
|
||||
|
||||
In Python 2.4a3 (to be released this Thursday), everything remains
|
||||
as currently in CVS. For 2.4b1, I will consider a change of @ to
|
||||
some other single character, even though I think that @ has the
|
||||
advantage of being the same character used by a similar feature
|
||||
in Java. It's been argued that it's not quite the same, since @
|
||||
in Java is used for attributes that don't change semantics. But
|
||||
Python's dynamic nature makes that its syntactic elements never mean
|
||||
quite the same thing as similar constructs in other languages, and
|
||||
there is definitely significant overlap. Regarding the impact on
|
||||
3rd party tools: IPython's author doesn't think there's going to be
|
||||
much impact; Leo's author has said that Leo will survive (although
|
||||
it will cause him and his users some transitional pain). I actually
|
||||
expect that picking a character that's already used elsewhere in
|
||||
Python's syntax might be harder for external tools to adapt to,
|
||||
since parsing will have to be more subtle in that case. But I'm
|
||||
frankly undecided, so there's some wiggle room here. I don't want
|
||||
to consider further syntactic alternatives at this point: the buck
|
||||
has to stop at some point, everyone has had their say, and the show
|
||||
must go on.
|
||||
|
||||
.. _Python wiki:
|
||||
http://www.python.org/moin/PythonDecorators
|
||||
.. _subsequently rejected:
|
||||
http://mail.python.org/pipermail/python-dev/2004-September/048518.html
|
||||
|
||||
|
||||
Community Consensus
|
||||
-------------------
|
||||
|
||||
The consensus that emerged was for the proposed J2 syntax: the new
|
||||
keyword ``using`` prefixing a block of decorators before the ``def``
|
||||
statement. For example::
|
||||
[editor's note: should this section be removed now?]
|
||||
|
||||
The consensus that emerged on comp.lang.python was the proposed J2
|
||||
syntax (the "J2" was how it was referenced on the PythonDecorators wiki
|
||||
page): the new keyword ``using`` prefixing a block of decorators before
|
||||
the ``def`` statement. For example::
|
||||
|
||||
using:
|
||||
classmethod
|
||||
|
@ -613,15 +670,21 @@ Sparks produced `a patch`_.
|
|||
.. _a patch:
|
||||
http://www.python.org/sf/1013835
|
||||
|
||||
As noted previously, Guido rejected this form, outlining his problems
|
||||
with it in `a message`_ to python-dev and comp.lang.python.
|
||||
|
||||
.. _a message:
|
||||
http://mail.python.org/pipermail/python-dev/2004-September/048518.html
|
||||
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Much of the discussion on ``comp.lang.python`` and the ``python-dev``
|
||||
mailing list focuses on the use of decorators as a cleaner way to use
|
||||
the ``staticmethod()`` and ``classmethod()`` builtins. This
|
||||
capability is much more powerful than that. This section presents
|
||||
some examples of use.
|
||||
the ``staticmethod()`` and ``classmethod()`` builtins. This capability
|
||||
is much more powerful than that. This section presents some examples of
|
||||
use.
|
||||
|
||||
1. Define a function to be executed at exit. Note that the function
|
||||
isn't actually "wrapped" in the usual sense. ::
|
||||
|
@ -639,9 +702,8 @@ some examples of use.
|
|||
is for example purposes only.
|
||||
|
||||
2. Define a class with a singleton instance. Note that once the class
|
||||
disappears enterprising programmers would have to be more creative
|
||||
to create more instances. (From Shane Hathaway on ``python-dev``.)
|
||||
::
|
||||
disappears enterprising programmers would have to be more creative to
|
||||
create more instances. (From Shane Hathaway on ``python-dev``.) ::
|
||||
|
||||
def singleton(cls):
|
||||
instances = {}
|
||||
|
@ -734,14 +796,17 @@ Open Issues
|
|||
===========
|
||||
|
||||
1. It's not yet certain that class decorators will be incorporated
|
||||
into the language at this point. Guido expressed skepticism about
|
||||
into the language at a future point. Guido expressed skepticism about
|
||||
the concept, but various people have made some `strong arguments`_
|
||||
(search for ``PEP 318 -- posting draft``) on their behalf in
|
||||
``python-dev``.
|
||||
``python-dev``. It's exceedingly unlikely that class decorators
|
||||
will be in Python 2.4.
|
||||
|
||||
.. _strong arguments:
|
||||
http://mail.python.org/pipermail/python-dev/2004-March/thread.html
|
||||
|
||||
2. The choice of the ``@`` character will be re-examined before
|
||||
Python 2.4b1.
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
|
Loading…
Reference in New Issue