Differences between revisions 16 and 136 (spanning 120 versions)
Revision 16 as of 2004-08-05 20:29:00
Size: 5961
Editor: 66
Comment:
Revision 136 as of 2004-10-21 18:36:55
Size: 2064
Editor: pcp07851797pcs
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
Support for decorators was proposed for Python in [http://www.python.org/peps/pep-0318.html PEP 318], and will be implemented in Python 2.4. [[TableOfContents()]]
Line 3: Line 3:
== What is a decorator == == What is a Decorator ==
Line 5: Line 5:
A decorator is a software design pattern. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated. A decorator is the name used for a software design pattern. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.
Line 11: Line 11:
== Debate about decorators in Python == == What is a Python Decorator ==
Line 13: Line 13:
The winning syntax as of now uses the '@' symbol, as described in [http://mail.python.org/pipermail/python-dev/2004-June/045516.html this message]. Mark Russell implemented this version. [http://mail.python.org/pipermail/patches/2004-July/015452.html Here] is the message describing the patch he checked in. The "decorators" we talk about with concern to Python are not exactly the same thing as the DecoratorPattern described above. A Python decorator is a specific change to the Python syntax that allows us to more conveniently alter functions and methods (and possibly classes in a future version). This supports more readable applications of the DecoratorPattern but also other uses as well.
Line 15: Line 15:
There has been a long discussion about the syntax to use for decorators in Python. See for example these threads: Support for the decorator syntax was proposed for Python in [http://www.python.org/peps/pep-0318.html PEP 318], and will be implemented in Python 2.4.
Line 17: Line 17:
 * http://article.gmane.org/gmane.comp.python.devel/61569
 * http://www.livejournal.com/users/jcalderone/3913.html
Note that the current proposal actually only decorates functions (including methods). Extending it to classes or even arbitrary code is possible, but Guido wasn't sure it made sense. (Later versions might become more permissive, but they can't easily snatch functionality back.)

== The Syntax for Python Decorators ==

The syntax for decorators uses the '@' symbol, as described in [http://mail.python.org/pipermail/python-dev/2004-June/045516.html this message]. Mark Russell implemented this version. [http://mail.python.org/pipermail/patches/2004-July/015452.html Here] is the message describing the patch he checked in.

There was a long discussion about the syntax to use for decorators in Python. Many different proposals were suggested: see PythonDecoratorProposals.
Line 28: Line 33:
Line 31: Line 35:

== Related Resources ==

See also: MixIns, MetaClasses

== Current Decorator Proposals ==

After the @decorator syntax was "accepted", lots of people threw up alarms and a huge series of threads started exploding on Python-dev. Here are the current alternatives that I could find that are being argued, with pros and cons:

I give two examples that might be common uses in the future. Classmethod declarations, and something like static typing (adapters), declaring what type parameters a function expects and returns.

'''A. pie decorator syntax'''
{{{
@classmethod
def foo(arg1,arg2):
    ...

@accepts(int,int)
@returns(float)
def bar(low,high):
    ...
}}}
 * + Java-like, so not completely unknown to everyone.
 * + Makes the syntax obvious visually
 * + Will not be silently ignored
 * + Compile-time
 * + Seperate from the def syntax (desired by some for making decoration stand out and keeping def the same)
 * - Seperate from the def syntax (undesired by some for simple decorators like classmethod/staticmethod)
 * - Ugly?
 * - The @ special character is used in IPython (...)
 * - Punctuation-based syntax raises Perlfears.
 * - Does not nessecarily
    
'''B. list-before-def syntax'''
{{{
[classmethod]
def foo(arg1,arg2):
    ...

[accepts(int,int), returns(float)]
def bar(low,high):
    ...
}}}
 * + C# like
 * + Can be made backwards compatible-ish, with a "hack"
 * + Doesn't cause breakage in existing code-searching tools
 * - Doesn't cause breakage in existing code-searching tools
----- /!\ Edit conflict! Other version: -----
 * - Would not work an interactive mode (list would be interpreted right away)
----- /!\ Edit conflict! Your version: -----
----- /!\ End of edit conflict -----
 * - EuroPython didn't like it ( why? )
 * - The backwards compatability wouldn't be portable to Jython
 * - Looks like a normal expression, but has "magic" behavior of altering a function object


'''C. list-after-def syntax'''
{{{
def foo(arg1,arg2) [classmethod]:
    ...

def bar(low,high) [accepts(int,int), returns(float)]:
    ...
}}}
 * + Also somewhat C#-like
 * + Was a "community favorite" at one time
 * + Clearly a part of function declaration
 * + Looks ok for simple decorators such as classmethod
 * + Won't break simplistic code analyzers or grep for function def
 * - Long lists of decorators/arguments cause ugly line wraps
 * - Guido didn't like (maybe because of line wrap issue?)
 * - Adds 'magic' behavior to a normal python expression (lists).

'''D. list at top of function body syntax'''
{{{
def foo(arg1,arg2):
    [classmethod]
    ...

def bar(low,high):
    [accepts(int,int), returns(float)]
    ...
}}}
 * + Also somewhat C#-like
 * + Consistent with how docstrings are used.
 * + Looks ok for simple or complex decorators
 * + Won't break simplistic code analyzers or grep for function def
 * + Solves line wrap problem with above proposal
 * 0 There is a hack that implements this now [http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286147 here].
 * - Guido's europython presentation said this didn't win out, but not why
 * - Adds 'magic' behavior to a normal python expression (lists).
 * 0 Perhaps decorators should be allowed before or after the docstring. If you have to choose, I'd choose making it before the docstring.

'''E. pie decorator at top of function body syntax'''
{{{
def foo(arg1,arg2):
    @classmethod
    ...

def bar(low,high):
    @accepts(int,int)
    @returns(float)
    ...
}}}
 * Same as above but with pie syntax.
 * Could use @doc to as a docstring alternative

'''F. inline syntax'''
{{{
def classmethod foo(arg1,arg2):
    ...

?
}}}
 * + Simple
 * + Obviousely attached to the function
 * - Does not allow for arguments to the decorator inline, or multiple decorators
 * - The natural place where everyone looks for the function name now is a possible container for other information
 * - Complicates things like colorization and other functions of helper tools
    
'''G. as decorator'''
{{{
as classmethod
def foo(arg1,arg2):
    ...

?
}}}
 * + Non-punctuation based
 * + Does not use an existing mechanism with 'magic' behavior
 * - Guido specifically vetos: "as" means "rename" in too many logical, common places that are in-use, and decorators do not rename.
    
'''H. with decorator, possibly indented?'''
{{{
with classmethod:
    def foo(arg1,arg2):
        ...

?
}}}
 * + The benefits of "as" without the renaming oddity.
 * + Reads as, "with decorator define function", which seems accurate. Such as, "with staticmethod define foobaction=savepage
See PythonDecoratorLibrary for more complex and real-world examples. See also MixIns and MetaClasses for related resources.

TableOfContents()

What is a Decorator

A decorator is the name used for a software design pattern. Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated.

For more information about the decorator pattern in general, see:

What is a Python Decorator

The "decorators" we talk about with concern to Python are not exactly the same thing as the DecoratorPattern described above. A Python decorator is a specific change to the Python syntax that allows us to more conveniently alter functions and methods (and possibly classes in a future version). This supports more readable applications of the DecoratorPattern but also other uses as well.

Support for the decorator syntax was proposed for Python in [http://www.python.org/peps/pep-0318.html PEP 318], and will be implemented in Python 2.4.

Note that the current proposal actually only decorates functions (including methods). Extending it to classes or even arbitrary code is possible, but Guido wasn't sure it made sense. (Later versions might become more permissive, but they can't easily snatch functionality back.)

The Syntax for Python Decorators

The syntax for decorators uses the '@' symbol, as described in [http://mail.python.org/pipermail/python-dev/2004-June/045516.html this message]. Mark Russell implemented this version. [http://mail.python.org/pipermail/patches/2004-July/015452.html Here] is the message describing the patch he checked in.

There was a long discussion about the syntax to use for decorators in Python. Many different proposals were suggested: see PythonDecoratorProposals.

Examples

   1 @classmethod
   2 def foo (arg1, arg2):
   3     ....

See PythonDecoratorLibrary for more complex and real-world examples. See also MixIns and MetaClasses for related resources.

PythonDecorators (last edited 2016-05-20 20:14:18 by FranciscoReyes)

Unable to edit the page? See the FrontPage for instructions.