Python decorators are a powerful feature of the language that allows you to modify or extend the behavior of a function or a class without modifying its source code. A decorator is basically a function that takes another function or class as an argument and returns a new function or class that can be used instead of the original one.
In this tutorial, I will cover the following topics:
- What are decorators in Python?
- How to define and use decorators?
- Commonly used Built-in decorators
- Examples of decorators
What are decorators in Python?
Decorators are functions that take another function as an argument and return a new function. The new function is a modified version of the original function, with additional behavior added by the decorator. This makes them a powerful tool for separating concerns and keeping code modular.
How to use decorators?
We can simply define a function that takes another function as an argument and returns a new function that has the additional behavior. Here’s a simple example:
|
|
This my_decorator
function calls the fun inside its wrapper.
|
|
The code above is the same as:
|
|
Both will output:
|
|
In this example, my_decorator
is a function that takes func
and returns a new function wrapper
that has additional behavior, which is printing two lines before and after calling the passed original function.
We then use the decorator by calling my_decorator
with the say_hello
function as an argument or by using the @my_decorator
syntax and assigning the result to say_hello
. We can then call say_hello
as usual, and the decorator’s behavior will be added.
Surely using @ is the preferred form. Simply put we read this block:
@my_decorator
def say_hello():
as:
Pass
say_hello
tomy_decorator
and replace it with the returned version.
Examples of decorators
Let’s look at some more examples of decorators in Python.
- Simple decorator:
|
|
- Decorator with arguments:
|
|
In this example, we define a decorator that takes an argument num
and returns a decorator function that takes another function as an argument and returns a new function that repeats the original function num
times. We use the decorator by calling repeat(num=3)
to get the decorator function, and then applying it to say_hello
using the @ syntax.
output:
|
|
- Class decorator
|
|
We can also define our decorator as a class. Then we need to assign it to the class in its constructor. The output is the same as the second example.
Built-in Decorators
Python has several decorators that can be used to modify methods. Here are a few important ones:
- @property:
the @property
decorator is used to define a method as a property of a class. When a method is decorated with @property
, it can be accessed like an attribute, without the need to call the method explicitly.
In other words, @property
allows you to define a method as if it were an attribute of the class, which makes it easier to use and more intuitive for other developers who may be using your code.
Here is an example of how to use @property
:
|
|
In this example, we define a Circle
class that has a radius attribute and a diameter property, which is calculated based on the radius. The diameter property is defined using @property
, which means that it can be accessed like an attribute.
We also define a diameter setter
method, which allows us to set the diameter and automatically updates the radius based on the new value. This is done using the @diameter.setter
decorator, which is used to define a method that sets the value of the diameter property.
When we create an instance of the Circle
class and access the diameter property, it calculates the diameter based on the radius. When we set the diameter property, it updates the radius and recalculates the diameter.
- @staticmethod:
This decorator is used to define a static method in a class. A static method is a method that belongs to a class rather than an instance of a class.
|
|
- @classmethod:
This decorator is used to define a class method in a class. A class method is a method that takes the class itself as its first argument, rather than an instance of the class.
|
|
- @abstractmethod:
This decorator is used to define an abstract method in an abstract base class. An abstract method is a method that is defined in the base class but has no implementation.
|
|
- @lru_cache:
This decorator is used to cache the result of a function call, so that the next time the function is called with the same arguments, the cached result is returned instead of re-evaluating the function.
|
|
These are just a few examples of the many decorators available in Python. Decorators can be a powerful tool for modifying the behavior of functions and methods, and can help make your code more modular and easier to read.