August 09, 2004
Python Decorators

Python-land seems to have descended into chaos while I've been away. I suppose I'd better leave someone in charge next time I go on holiday. ;-)

The source of the problem is function decoration, which offers a way to mutate a function or method. The cardinal example of a function decorator might be staticmethod(), Python's way of building static methods. Currently, you have to declare and code the function, then call staticmethod() passing your function as an argument:

class MyClass:
    def my_method(arg1, arg2, ...):
        whatever
    my_method = staticmethod(my_method)

This is bad for two reasons; firstly, the code which defines my_method as static is not in the same place as the definition of the function itself - it may be a long way away in the case of long methods, and secondly there's the non-critical but irritating fact that you need to enter the method's name three times, violating the DRY principal.

Enter function decorators. The current implementation spells decoration like this:

class MyClass:
    @staticmethod
    def my_method(arg1, arg2, ...):
        whatever

Now, I dislike this for two reasons. Firstly, it's ugly. This matters. Secondly, it's not in the function - it doesn't really look like part of it. I'm not alone in disliking this syntax.

I prefer Phillip J. Eby's list-after-def proposal:

class MyClass:
    def my_method(arg1, arg2, ...) [staticmethod]:
        whatever

Much nicer, at least in simple cases. Things get more complicated where you have multiple decorators, and/or the decorators take arguments themselves, but I don't believe that these will come up too often - especially not the second.

Anyway, that's enough from me; this discussion has generated over six hundred emails to python-dev over the last week, and I don't have anything new to add. I'm sure that whatever Guido ends up deciding on, it'll be OK in the end. He knows what he's doing.

I've not even started reading last week's c.l.py. ;-)

Posted to Python by Simon Brunning at August 09, 2004 01:43 PM
Comments

A little typo - there shouldn't be a "def" in the statement "def my_method = staticmethod(my_method)".

Posted by: Hamish Lawson on August 9, 2004 03:16 PM

Yes, the line should just read;

staticmethod(my_method)

Posted by: Andy Todd on August 9, 2004 03:31 PM

Fixed. Thanks, guys.

Posted by: Simon Brunning on August 9, 2004 04:05 PM

I hate attributes (the '@' thing) too. Why not borrow from Java land and add a keyword like this:

def static myStaticMethod

It seems a little less syntax heavy than [static] and much better than @static

Posted by: Sam Newman on August 9, 2004 04:57 PM

The Java-like syntax was proposed, but with Python you can define your own decorators, so they can't be keywords.

What's more, there can be any number of them, and they can take arguments, so it can get pretty ugly...

Posted by: Simon Brunning on August 9, 2004 05:30 PM

acually, I think we borrowed this from javaland. the @thing is the annotation syntax IIRC (java 1.5)

Posted by: gabriele on August 9, 2004 05:40 PM

I have to disagree with there not being more complicated cases. I can, just of the top of my head, can imagine some pretty complicated cases. For example: threading (run function in a seperate thread, so as to not block), locking (for multithreading apps), function attributtes, easier doctest and unittest, support for pre and post conditions, profiling, interfaces, properties, and the obvious static and class methods.

A big project may very well have many of these descriptors per function, which can make things pretty ugly. So, while I really dont like the @ syntax as well, it does scale better to when you have 5 decorators where some of them will have arguments.

Posted by: Daniel Brodie on August 9, 2004 08:22 PM

I'm fairly sure there have been more posts on python-dev on this subject than comp.lang.python.

The comp.lang.python discussion is probably even more repetitive.

Posted by: Michael Hudson on August 10, 2004 02:02 PM

Why is such intelligent content being presented with such dumb typography? Is there anyone who really thinks that white type on a dark gray background is a Good Thing?

Posted by: Asp on August 13, 2004 06:50 PM

Sorry, Asp, but *I* like it.

Posted by: Simon Brunning on August 16, 2004 01:05 PM

Very good post. (Asp, I disagree: the colourscheme is minimalistic and easy on the eyes. I quite approve).

I am saddened to see this decorator syntax in Python as well. I was just today evangelizing Python as a great language for all it's cleanliness.

I suppose I'll get used to function decorators, the one thing I wish they'd do however, is at least change the name. To me, 'static' means something unchanging and fixed. Technically all methods are, so a newbie might ask, "what's the difference in a static method"?

I can't think of a keyword off-hand, but perhaps something like "shared" or "sharedacrossinstances" (too wordy, but you get the idea) or the like.

Anyways, I'm sure the same discussion came out of the filter(), lambda(), and reduce() components, so I'll probably get used to it. But I'll sigh nonetheless.

Sigh.

Posted by: Eddie Parker on April 22, 2005 01:02 AM

Reading this from the enlightened time of The Future (tm), I chuckle at your comment:
"Things get more complicated where you have multiple decorators, and/or the decorators take arguments themselves, but I don't believe that these will come up too often - especially not the second."

Using decorators with arguments is where half their flexibility comes from, IMHO. You can then easily write decorators for (using the now-accepted syntax) type validation ("@types(int, str, object, ...)"), hooking/event handling ("@handle(myWidget, 'click')"), documenting/validating ("@new('v2.4')"), and such.

Of course, I'm a little high on the elegance of Python and the usefulness of defining classes where the Python reference says a "callable" is needed.

Posted by: Jamie on February 26, 2007 11:16 PM

mens penis amd balls gaymale piss masturbation stories nostalgia merchanvhs movies naked ebony female

Posted by: Sasha on October 27, 2008 07:44 AM

girl hockey players hoodcanalbridge girl scout uniforms tulare distinguish between sexual and asexual reproduction in the hydra.

Posted by: Future_dim on October 29, 2008 06:29 AM

Posted by: Future_dim on October 30, 2008 04:15 AM

Posted by: Future_dim on November 1, 2008 04:25 AM

Posted by: Future_dim on November 1, 2008 04:25 AM

Posted by: Future_dim on November 1, 2008 04:25 AM

Posted by: Future_dim on November 1, 2008 04:25 AM

Posted by: Future_dim on November 4, 2008 02:17 PM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?