

Understanding Python Decorators - hiwaylon
http://stackoverflow.com/questions/739654/understanding-python-decorators/1594484#1594484

======
jackowayed
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)

~~~
omaranto
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. :)

~~~
rbonvall
That's exactly how I see it. One could have also, for example, lists of
decorators,

    
    
        @a[1]
        def f(x):
            ...

------
peteretep
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...](http://search.cpan.org/~erwan/Python-
Decorator-0.03/lib/Python/Decorator.pm)

~~~
grncdr
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.

------
yason
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.

~~~
sebkomianos
I am pretty sure the Python community is always up for better explanations!

~~~
DasIch
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.

~~~
urschrei
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.

------
SoftwareMaven
His answer to metaclasses is worth a read, too:
[http://stackoverflow.com/questions/100003/what-is-a-
metaclas...](http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-
python/6581949#6581949)

------
salem
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.

------
buckwild
I use decorators all of the time. However, I still learned something while
reading this comprehensive explanation. Totally worth adding to my bookmarks.

------
awegawef
A very good response, glad to see it on SO. It's also worth mentioning that
decorators can be classes.

------
krosaen
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.

------
kingkilr
Not sure where he gets that Python ships a memoize decorator.

~~~
ddbeck
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....](http://docs.python.org/dev/library/functools.html#functools.lru_cache)

~~~
kingkilr
I'm aware, there was also almost an LFU cache decorator in there.

------
mykhal
less is more

