Python Decorators Explained with Examples

Enhance Your Functions with Decorators

Learn how to extend and modify the behavior of your functions using Python decorators. This tutorial explains the concept, provides practical examples, and shows you how to write your own decorators.

Programming
Author
Affiliation
Published

February 5, 2024

Modified

February 7, 2025

Keywords

Python decorators, decorators in Python

Introduction

Python decorators are a powerful tool that allow you to extend and modify the behavior of functions without permanently modifying their code. They provide a clean and expressive way to add functionality to your functions, making your code more modular and easier to maintain.

In this tutorial, we’ll explain the concept of decorators, show you how they work, and provide practical examples to help you incorporate decorators into your own projects.



What are Decorators?

A decorator in Python is a function that takes another function as an argument, adds some functionality to it, and returns a new function. Decorators are often used for:
- Logging: Recording when functions are called.
- Access Control: Checking permissions before running a function.
- Caching: Storing results of expensive function calls.
- Timing: Measuring the execution time of functions.

How Decorators Work

When you apply a decorator to a function using the @decorator_name syntax, Python passes the decorated function to the decorator. The decorator then returns a new function that enhances or modifies the original function’s behavior.

Basic Decorator Example

Below is a simple example that demonstrates how to create and use a decorator to add behavior before and after a function call.

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before the function call")
        result = func(*args, **kwargs)
        print("After the function call")
        return result
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")

Output:

Before the function call
Hello, Alice!
After the function call

Advanced Example: Decorator with Arguments

Decorators can also be designed to accept arguments, which allows for even more flexible behavior modifications.

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(n):
                print(f"Repeat {i+1}/{n}:")
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

greet("Bob")

Output:

Repeat 1/3:
Hello, Bob!
Repeat 2/3:
Hello, Bob!
Repeat 3/3:
Hello, Bob!

Best Practices for Using Decorators

  • Keep It Simple:
    Write small, focused decorators that do one thing well.

  • Use functools.wraps:
    When writing decorators, use functools.wraps to preserve the metadata of the original function.

    import functools
    
    def my_decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print("Before the function call")
            result = func(*args, **kwargs)
            print("After the function call")
            return result
        return wrapper
  • Document Your Decorators:
    Clearly comment and document the purpose and usage of each decorator.

Conclusion

Decorators in Python provide a flexible and elegant way to modify the behavior of functions. By mastering decorators, you can write more modular and reusable code, enhance functionality without code duplication, and implement cross-cutting concerns like logging and error handling more cleanly. Experiment with the examples provided here, and try creating your own decorators to see how they can simplify your coding tasks.

Further Reading

Happy coding, and enjoy enhancing your functions with decorators!

Back to top

Reuse

Citation

BibTeX citation:
@online{kassambara2024,
  author = {Kassambara, Alboukadel},
  title = {Python {Decorators} {Explained} with {Examples}},
  date = {2024-02-05},
  url = {https://www.datanovia.com/learn/programming/python/advanced/decorators-explained.html},
  langid = {en}
}
For attribution, please cite this work as:
Kassambara, Alboukadel. 2024. “Python Decorators Explained with Examples.” February 5, 2024. https://www.datanovia.com/learn/programming/python/advanced/decorators-explained.html.