Decorators That Take Parameters
Sometimes you want to configure a decorator:
@repeat(3)
def say_hello():
print("Hello!")
This requires an extra layer - a function that returns a decorator:
def repeat(times):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
func(*args, **kwargs)
return wrapper
return decorator
Think of it as: repeat(3) returns a decorator, which is then applied to say_hello.
Three levels:
- Outer function receives the parameter (
times) - Middle function receives the function to decorate (
func) - Inner function is the actual wrapper
This pattern is common in frameworks - Flask's @app.route("/path") works this way.
I explain parameterized decorators in my Python Decorators course.