Advanced Python Decorators: Passing Arguments to Your Wrappers

3D illustration of a function wrapper with adjustable control dials, representing passing arguments to Python decorators.

In our Basic Decorator Guide, we built a simple @log_decorator. But what if we want to configure the decorator itself? Like this: @repeat(times=5). Now it’s time to explore Advanced Python Decorators and how to use them.

To achieve the configuration we need three levels of nested functions. It looks confusing at first, but it follows a pattern.

The Pattern

  1. Outer Function: Accepts the decorator’s arguments (e.g., times=5).
  2. Middle Function: Accepts the function being decorated (standard decorator).
  3. Inner Function: The actual wrapper that runs the code.
# 1. Outer level receives the arguments
def repeat(times):
    # 2. Middle level receives the function
    def decorator_func(original_func):
        # 3. Inner level wraps the logic
        def wrapper_func(*args, **kwargs):
            for _ in range(times):
                original_func(*args, **kwargs)
        return wrapper_func
    return decorator_func

Using It

Now we can utilise advanced features offered in Python decorators and employ our configurable decorator!

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

greet("Alice")

Output:

Hello, Alice!
Hello, Alice!
Hello, Alice!

This is exactly how complex frameworks like Flask allow you to do @app.route("/home", methods=["GET", "POST"]).

Key Takeaways

  • The article discusses configuring decorators in Python, specifically using @repeat(times=5).
  • To create advanced Python decorators, use three nested functions: an outer function for arguments, a middle function for the main function, and an inner function as the wrapper.
  • This pattern allows for flexible functionality similar to that in frameworks like Flask with @app.route.

Similar Posts

Leave a Reply