An Introduction to Python Decorators
Python decorators are a powerful tool for modifying functions and methods. They allow you to wrap another function in order to extend the behavior of the wrapped function, without permanently modifying the code of the wrapped function.
In this article, we will take a look at what decorators are, how they work, and how you can use them in your own code. We will also go over some common use cases for decorators and provide some examples of how to implement them.
What are Decorators?
At a high level, a decorator is a function that takes another function and extends the behavior of the wrapped function without explicitly modifying its code.
Here is a simple example of a decorator in Python:
The output of this code would be:
In this example, the my_decorator
function is a decorator. It takes the say_hello
function as an argument and returns a wrapper function that adds some additional behavior before and after calling the original say_hello
function.
The decorator syntax in Python is slightly more concise than the above example. Here is the same code using the decorator syntax:
The output of this code is the same as the previous example. The @my_decorator
syntax is equivalent to calling say_hello = my_decorator(say_hello)
.
How Do Decorators Work?
Decorators work by taking a function as an argument and returning a modified version of that function. The modified version of the function is often referred to as a wrapper function.
The wrapper function is defined inside the decorator and typically contains additional code that is executed before and after calling the original function. The wrapper function may also modify the arguments and return value of the original function.
In the above example, the wrapper
function adds some text to the output of the say_hello
function. However, the say_hello
function itself is not modified. This allows us to reuse the decorator with different functions and add the same behavior to each of them.
Use Cases for Decorators
Decorators are often used to add additional functionality to a function without modifying the code of the function itself. Here are a few common use cases for decorators:
- Logging: You can use a decorator to add logging to a function. This can be useful for debugging or for tracking the usage of a function.
- Timing: You can use a decorator to measure the execution time of a function. This can be useful for performance optimization or for understanding the performance characteristics of a function
- Caching: You can use a decorator to cache the results of a function. This can be useful for improving the performance of a function that is called repeatedly with the same arguments.
- Authentication: You can use a decorator to require authentication for a function. This can be useful for adding security to a function that should only be accessible to certain users.
Examples of Decorators
Here are a few examples of decorators that demonstrate some of the use cases described above:
Logging Decorator
In line 6 we made the function sleep for 2 seconds in order to make the function take little longer.
The output of this code would be a log message similar to the following:
Timing Decorator
The following decorator measures the execution time of a function. It prints the execution time to the console.
The output of this code would be:
Caching Decorator
The following decorator implements a simple cache for a function. It stores the results of the function in a dictionary and returns the cached result if the function is called with the same arguments.
The first call to add
will compute the result and store it in the cache. The second call to add
will retrieve the result from the cache and return it without calling the add
function.
Authentication Decorator
The following decorator requires a user to be authenticated before calling the decorated function. If the user is not authenticated, it raises an exception.
In this example, the seeInfo
function will only be executed if the authenticated
variable is True
. If it is False
, an exception will be raised.
Conclusion
In this article, we have learned what Python decorators are and how they work. We have also seen some examples of how decorators can be used to extend the functionality of a function without modifying its code.
Decorators are a powerful tool for modifying functions in a flexible and reusable way. I hope this has given you a good understanding of how to use them in your own code.
Check Out my YouTube Channel for more programming content.
See you in future articles.