Many documents online concern about the syntax of decorator. But I want to know where and how is the decorator used? Is the decorator just used to execute extra codes before and after the decorated function? Or maybe there is other usage?
-
@Bakuriu I Don't think this is a duplicate This question is about "why". The one you mention is about "How". – luc Nov 19 '12 at 08:43
-
@Tadeck I just find it can add extra code before and after the execution of the decorated function. What other usage? – hbprotoss Nov 19 '12 at 08:44
-
1Plenty of examples here: http://wiki.python.org/moin/PythonDecoratorLibrary – georg Nov 19 '12 at 08:48
-
@luc The question(and related answers) I linked not only explains how to write decorators, it explains in details what happens when you decorate a function, using nice code examples. So it both covers how and what you can do with them. – Bakuriu Nov 19 '12 at 12:14
-
I think I should close this question. Looking back after 10 years, at my point of view now, it is a simple question asked by a newbie. Decorator is just an impl for Decorator Pattern in python@luc Bakuriu – hbprotoss Aug 15 '22 at 08:47
3 Answers
The decorator syntax is powerful:
@decorator
def foo(...):
...
is equivalent to
def foo(...):
...
foo = decorator(foo)
That means that decorators can do basically anything -- they don't have to have any relation to the decorated function! Examples include:
- memoising a recursive function (
functools.lru_cache
) - logging all calls to a function
- implementing the descriptor functionality (
property
) - marking a method as static (
staticmethod
)

- 120,462
- 19
- 136
- 170
-
On a side note, decorators can return *any* object, so when you call a decorated function you can't assume that the "real" function is called at all(even though this is what happens in 99.9999% of the cases). – Bakuriu Nov 19 '12 at 12:17
A good practical example would be from Python's very own unittest framework where it makes use of decorators to skip tests and expected failures:
Skipping a test is simply a matter of using the skip() decorator or one of its conditional variants.
Basic skipping looks like this:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass

- 1,016
- 8
- 10
An decorator wraps around an method or even a whole class and delivers the ability to manipulate for example the call of an method. I very often use an @Singleton decorator to create an singleton.
Decorators are extremely powerful and really cool concept.
Look at this book for understanding them: http://amzn.com/B006ZHJSIM

- 956
- 13
- 32