Photo by Vitor Santos on Unsplash
A Tale of Python: An Introduction to Decorators for Beginners
Learn how decorators can improve the capabilities and performance of your functions in Python...
Table of contents
Python is a high-level, interpreted programming language that has recently gained immense popularity. It's a versatile language with a wide range of features that make it easy to write clean, efficient, and powerful code.
One key feature that makes Python such a great language to work with is its support for decorators. In this article, we will see an introduction to this powerful characteristic of Python. Being able to fully understand it will allow us to keep taking advantage of the perks of this language that can be used in our everyday tasks.
What is a Decorator?
In Python, a decorator is a special type of function that can modify the behavior of another function without changing its source code. Decorators can be used to add new functionality to existing functions, modify the output of a function, or provide additional behavior when a function is called.
To use a decorator, you define it as a regular Python function and then apply it to another function using the @ symbol. Let's take a look at a simple example:
def my_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
In this example, we define a decorator function called my_decorator
that takes a function as an argument and returns a new function called wrapper
. Inside wrapper
, we print a message before and after calling the original function.
We then apply the my_decorator
function to the say_hello
function using the @ symbol. When we call say_hello
, it calls the wrapper function created by the my_decorator
function.
The output of this code would be:
Before the function is called.
Hello!
After the function is called.
As you can see, the wrapper
function is modifying the behavior of the say_hello
function by adding additional output before and after it is called.
Another way to apply a decorator is to call the decorator function explicitly and pass the original function as an argument:
def my_decorator(func):
def wrapper():
print("Before the function is called.")
func()
print("After the function is called.")
return wrapper
def say_hello():
print("Hello!")
decorated_function = my_decorator(say_hello)
decorated_function()
In this case, we create a decorator function called my_decorator
and a regular function called say_hello
. We then call the my_decorator
function and pass say_hello
as an argument, which returns a new function called wrapper
. We then assign this new function to a variable called decorated_function
and call it.
The output of this code would be the same as the previous example:
Before the function is called.
Hello!
After the function is called.
Decorators can also take arguments. Let's take a look at an example:
def repeat(num_times):
def decorator_repeat(func):
def wrapper():
for i in range(num_times):
func()
return wrapper
return decorator_repeat
@repeat(num_times=3)
def say_hello():
print("Hello!")
say_hello()
In this example, we define a decorator function called repeat
that takes an argument num_times
. This function returns another decorator function called decorator_repeat
, which in turn returns the wrapper
function that calls the original function multiple times.
We then apply the repeat
decorator to the say_hello
function, passing in num_times=3
. When we call say_hello
, it calls the wrapper function created by the decorator_repeat
function, which calls say_hello
three times.
The output of this code would be:
Hello!
Hello!
Hello!
As you can see, the wrapper
function is modifying the behavior of the say_hello
function by calling it multiple times, as specified by the num_times
argument passed to the repeat
decorator.
Decorators can also be used to modify the output of a function. Let's take a look at an example:
def uppercase(func):
def wrapper():
original_result = func()
modified_result = original_result.upper()
return modified_result
return wrapper
@uppercase
def say_hello():
return "Hello!"
print(say_hello())
In this example, we define a decorator function called uppercase
that takes a function as an argument and returns a new function called wrapper
. Inside wrapper
, we call the original function and store its output in a variable called original_result
. We then modify this output by converting it to uppercase and return the modified result.
We then apply the uppercase
decorator to the say_hello
function. When we call say_hello
, it calls the wrapper function created by the uppercase
function.
The output of this code would be:
HELLO!
As you can see, the wrapper
function is modifying the output of the say_hello
function by converting it to uppercase.
Conclusions
In conclusion, decorators are a powerful feature in Python that allows you to modify the behavior of functions without changing their source code. Decorators can be used to add new functionality to existing functions, modify the output of a function, or provide additional behavior when a function is called.
Decorators can also take arguments, allowing you to customize their behavior for different use cases.
In this article, we saw examples of decorator functions that modify the behavior of other functions. Nevertheless, Python also allows us to decorate classes and use classes as decorators. This is a topic that we will be discussing in future articles, so stay tuned so you don't miss any new posts.
Understanding decorators is an important part of becoming a proficient Python programmer, and I hope this article has given you a good introduction to this powerful feature.
Note: This is the English translation of one of the articles published in another project that I have been collaborating on lately. It is an academy to teach programming topics using Python but taught in the Spanish language.
CodeXL Academy blog: A blog with Python content only in Spanish. Sometimes we publish translations of the articles published here for our English-speaking audience.
CodeXL Academy official website: Learn about everything we have to offer you.
Free newsletter: Receive updates every week about what's happening in the world of Python and our Academy.
Free and Paid courses: Discover our teaching materials in Spanish.
We felt like some of the articles published in Spanish should also be available for our English-speaking audience. So, stay tuned for more programming articles like this one.
See you soon!
๐ Hello, I'm Alberto, Software Developer at doWhile, Competitive Programmer, Teacher, and Fitness Enthusiast.
๐งก If you liked this article, consider sharing it.