
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)
To achieve the configuration needed in advanced Python decorators, we need three levels of nested functions. It looks confusing at first, but it follows a pattern.
The Pattern
- Outer Function: Accepts the decorator’s arguments (e.g.,
times=5). - Middle Function: Accepts the function being decorated (standard decorator).
- 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_funcUsing 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"]).





