Python decorators allow you to modify or extend the behavior of functions and methods without changing their actual code. When you use a Python decorator, you wrap a function with another function, which takes the original function as an argument and returns its modified version. This technique provides a simple way to implement higher-order functions in Python, enhancing code reusability and readability.
You can use decorators in various practical scenarios, such as logging, enforcing access control, caching results, or measuring execution time. To create a custom decorator, define a function that takes another function as an argument, creates a nested wrapper function, and returns the wrapper. When applying a decorator, you place @decorator
on the line before the function definition.
By the end of this tutorial, you’ll understand that:
- Python decorators allow you to wrap a function with another function to extend or modify its behavior without altering the original function’s code.
- Practical use cases for decorators include logging, enforcing access control, caching results, and measuring execution time.
- Custom decorators are written by defining a function that takes another function as an argument, defines a nested wrapper function, and returns the wrapper.
- Multiple decorators can be applied to a single function by stacking them, one per line, before the function definition.
- The order of decorators impacts the final output, as each decorator wraps the next, influencing the behavior of the decorated function.
You can find all the examples from this tutorial by downloading the accompanying materials below:
Get Your Code:Click here to download the free sample code that shows you how to create and use Python decorators.
Free Bonus:Click here to get access to a free "The Power of Python Decorators" guide that shows you three advanced decorator patterns and techniques you can use to write cleaner and more Pythonic programs.
Decorators Cheat Sheet:Click here to get access to a free three-page Python decorators cheat sheet that summarizes the techniques explained in this tutorial.
Decorators Q&A Transcript:Click here to get access to a 25-page chat log from our Python decorators Q&A session in the Real Python Community Slack where we discussed common decorator questions.
Take the Quiz: Test your knowledge with our interactive “Decorators” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
DecoratorsIn this quiz, you'll revisit the foundational concepts of what Python decorators are and how to create and use them.
Python Functions
In order to understand decorators, you must first understand some finer points of how functions work. There are many aspects to functions, but in the context of decorators, a function returns a value based on the given arguments. Here’s a basic example:
>>> defadd_one(number):... returnnumber+1...>>> add_one(2)3
In general, functions in Python may also have side effects rather than just turning an input into an output. The print()
function is an example of this: it returnsNone
while having the side effect of outputting something to the console. However, to understand decorators, it’s enough to think about functions as tools that turn given arguments into values.
First-Class Objects
In functional programming, you work almost entirely with pure functions that don’t have side effects. While not a purely functional language, Python supports many functional programming concepts, including treating functions as first-class objects.
This means that functions can be passed around and used as arguments, just like any other object like str
, int
, float
, list
, and so on. Consider the following three functions:
greeters.py
defsay_hello(name):returnf"Hello {name}"defbe_awesome(name):returnf"Yo {name}, together we're the awesomest!"defgreet_bob(greeter_func):returngreeter_func("Bob")
Here, say_hello()
and be_awesome()
are regular functions that expect a name given as a string. The greet_bob()
function, however, expects a function as its argument. You can, for example, pass it the say_hello()
or the be_awesome()
function.
To test your functions, you can run your code in interactive mode. You do this with the -i
flag. For example, if your code is in a file named greeters.py
, then you run python -i greeters.py
:
>>> greet_bob(say_hello)'Hello Bob'>>> greet_bob(be_awesome)'Yo Bob, together we're the awesomest!'
Note that greet_bob(say_hello)
refers to two functions, greet_bob()
and say_hello
, but in different ways. The say_hello
function is named without parentheses. This means that only a reference to the function is passed. The function isn’t executed. The greet_bob()
function, on the other hand, is written with parentheses, so it will be called as usual.
This is an important distinction that’s crucial for how functions work as first-class objects. A function name without parentheses is a reference to a function, while a function name with trailing parentheses calls the function and refers to its return value.
Inner Functions
It’s possible to define functionsinside other functions. Such functions are called inner functions. Here’s an example of a function with two inner functions:
Read the full article at https://realpython.com/primer-on-python-decorators/ »
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]