A Tale of Python: An Introduction to Decorators for Beginners

Learn how decorators can improve the capabilities and performance of your functions in Python...

ยท

5 min read

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.

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.

๐Ÿ”— All links | Twitter | LinkedIn

Did you find this article valuable?

Support Algorithmically Speaking by becoming a sponsor. Any amount is appreciated!

ย