News for hackers. Stuff that matters.
Re:Understanding Python Decorators by jackowayed on Sunday August 07, 2011 @04:52PM (#2857685)
Am I the only one who thinks it's a massive flaw that decorators that take args and decorators that don't are inherently different? That extra level of anonymous functions feels awful, and it's really confusing because a decorator that takes no args is @decorator whereas one that takes optional args is @decorator() if you just go with the defaults, and there is no way to make them both work.

Also, I wish they would integrate some of the stuff from this answer into the documentation, as it took me almost an hour to figure out how decorators that take arguments work and to discover that @decorator and @decorator() are irrevocably different. The documentation I found on decorators that take args was very brief. (I can't remember if I found any mention at all in the actual Python docs. I ended up learning it from mediocre, old blog posts)

Re:Understanding Python Decorators by kbd on Sunday August 07, 2011 @06:00PM (#2857867)
Armin Ronacher (prominent Python developer) included a critique of decorators in a post about a month ago making precisely your point:

> Decorators are somewhat of a pain because there is a difference between @foo and @foo(). If they were declared in a way that the former means the latter we would all be much happier now. Every time I want to introduce a parameter to a previously parameterless decorator makes me want to hit myself and the author of the decorator PEP with a stick.

http://lucumr.pocoo.org/2011/7/9/python-and-pola/

Discussed on HN too:

http://news.ycombinator.com/item?id=2744703

Re:Understanding Python Decorators by omaranto on Sunday August 07, 2011 @06:50PM (#2858031)
It only feels wrong because you think of them as decorators without arguments and decorators with arguments: they really are decorators stored in variables and decorators computed by function calls. :)
Re:Understanding Python Decorators by rbonvall on Monday August 08, 2011 @12:13AM (#2858737)
That's exactly how I see it. One could have also, for example, lists of decorators,

    @a[1]
    def f(x):
        ...
Re:Understanding Python Decorators by SoftwareMaven on Monday August 08, 2011 @12:50AM (#2858834)
I do. The people who don't are thinking from the implementor perspective instead of the user perspective.

I had a permission checking decorator that I allowed both syntaxes (the default permission check and a mre fine-grained check). The flaw makes for an ugly implementation.

Re:Understanding Python Decorators by andrewcooke on Sunday August 07, 2011 @06:43PM (#2858014)
one workaround is to make your decorators require keyword arguments (which often makes good sense from a documentation POV). you can then add a first keyword argument as gatekeeper, with default value None, and check whether it has been defined. if so, the decorator was used incorrectly.

you can see what i mean here - http://code.google.com/p/lepl/source/browse/src/lepl/matcher...

this doesn't fix the problem completely, of course, but it does mean that a user that types @foo instead of @foo() gets a helpful warning explaining exactly what they have done wrong.

Re:Understanding Python Decorators by jamii on Sunday August 07, 2011 @05:51PM (#2857833)
In your own code you can just wrap argument-less decorators in a function.

    def decorator():
      return some_library.decorator_with_no_args

    @decorator()
Re:Understanding Python Decorators by jackowayed on Sunday August 07, 2011 @05:52PM (#2857841)
But then @decorator doesn't work. I guess if I did that for every single decorator I use, I would at least have consistency. But that's not a very satisfying solution even ignoring the fact that now I have to wrap every zero-arg decorator I want to use.
Re:Understanding Python Decorators by peteretep on Sunday August 07, 2011 @04:29PM (#2857645)
Step 1: Huh, that's a pretty cool feature

Step 2: I bet I could ...

Step 3: Quick check of CPAN

Step 4: Zounds. http://search.cpan.org/~erwan/Python-Decorator-0.03/lib/Pyth...

Re:Understanding Python Decorators by grncdr on Sunday August 07, 2011 @10:16PM (#2858492)
That's pretty cool. I wonder if I could get away with using this at $work...

Not to mention, one could alter the implementation to remove the inconsistency people are complaining about in Python.

Re:Understanding Python Decorators by yason on Sunday August 07, 2011 @03:06PM (#2857442)
I must say that for such a simple concept as decorator, this answer surely used up all the wireframe there ever was allocated for making examples.
Re:Understanding Python Decorators by sebkomianos on Sunday August 07, 2011 @03:08PM (#2857445)
I am pretty sure the Python community is always up for better explanations!
Re:Understanding Python Decorators by DasIch on Sunday August 07, 2011 @03:52PM (#2857559)
Better explanations?

   @foo
   def bar():
       ...
Is syntax sugar for

   def bar():
       ...
   bar = foo(bar)

That is all there is to it. It's just syntax sugar to make this particular design pattern more convenient to use.

These explanations add more confusion then they dissolve and give off the impression that this is some kind of expert python foo which is clearly isn't.

Re:Understanding Python Decorators by urschrei on Sunday August 07, 2011 @04:19PM (#2857625)
Well, OK, but the answer also addresses other cases such as function/method decoration, passing arguments to the decorator itself, and passing arbitrary arguments. I agree that it's a little verbose, and the excessive comments and examples do detract from the clarity of the answer a little, but it's an excellent answer, nevertheless, if only because it leaves no use cases unexplored (excepting class decoration, but that's sufficiently orthogonal, I feel).

Your answer isn't wrong, but as an exercise in pedagogy (which is the point of SO, or at least one of its major aims) it leaves a lot to be desired, and wouldn't garner many upvotes. Not everyone understands what the term "syntax sugar" (and really, shouldn't that be 'syntactic sugar'?) means.

Re:Understanding Python Decorators by ttrtwrtwrtwr on Sunday August 07, 2011 @04:15PM (#2857612)
>That is all there is to it.

At it's most basic yes, but passing arguments to both the decorator and the decorated function are the real value of the article.

And there are examples, more than I need but they provide different ways of looking at the same thing that different people might find useful.

Re:Understanding Python Decorators by SoftwareMaven on Monday August 08, 2011 @12:52AM (#2858840)
His answer to metaclasses is worth a read, too: http://stackoverflow.com/questions/100003/what-is-a-metaclas...
Re:Understanding Python Decorators by salem on Sunday August 07, 2011 @10:54PM (#2858564)
Python decorators are extremely useful, especially for neatly adding caching. Style aside, it's extremely cool to be able to add LRU caching, or memcached for a function with one line of code.
Re:Understanding Python Decorators by buckwild on Sunday August 07, 2011 @04:45PM (#2857676)
I use decorators all of the time. However, I still learned something while reading this comprehensive explanation. Totally worth adding to my bookmarks.
Re:Understanding Python Decorators by awegawef on Sunday August 07, 2011 @06:38PM (#2858000)
A very good response, glad to see it on SO. It's also worth mentioning that decorators can be classes.
Re:Understanding Python Decorators by krosaen on Sunday August 07, 2011 @11:09PM (#2858595)
a nice use case for web apps: making sure the current user is logged in, and / or has permission to access a specific resource. removes a ton of boilerplate for redirecting to the login page or returning a 403. tornado makes use of this with the authenticated decorator.
Re:Understanding Python Decorators by kingkilr on Sunday August 07, 2011 @05:00PM (#2857705)
Not sure where he gets that Python ships a memoize decorator.
Re:Understanding Python Decorators by ddbeck on Sunday August 07, 2011 @05:24PM (#2857779)
While not actually called memoize, Python 3.2 ships with the lru_cache decorator in the standard library module functools.

http://docs.python.org/dev/library/functools.html#functools....

Re:Understanding Python Decorators by kingkilr on Sunday August 07, 2011 @05:31PM (#2857795)
I'm aware, there was also almost an LFU cache decorator in there.
Re:Understanding Python Decorators by mykhal on Sunday August 07, 2011 @03:40PM (#2857523)
less is more