How to Create Decorator with Arguments in Python
To create a decorator with arguments in Python, define a function that takes the decorator arguments and returns the actual decorator function. This returned decorator then takes the function to be decorated and wraps it, allowing you to use
@decorator(args) syntax.Syntax
A decorator with arguments requires three nested functions:
- Outer function: Takes the decorator arguments.
- Decorator function: Takes the function to decorate.
- Wrapper function: Runs code before/after calling the original function.
This structure allows passing arguments to the decorator while still wrapping the target function.
python
def decorator_with_args(arg1, arg2): def decorator(func): def wrapper(*args, **kwargs): # Code using arg1, arg2 before calling func result = func(*args, **kwargs) # Code using arg1, arg2 after calling func return result return wrapper return decorator
Example
This example shows a decorator that repeats a function call a specified number of times using an argument.
python
def repeat(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): func(*args, **kwargs) return wrapper return decorator @repeat(3) def say_hello(): print("Hello!") say_hello()
Output
Hello!
Hello!
Hello!
Common Pitfalls
Common mistakes include:
- Forgetting to return the wrapper function inside the decorator.
- Not using
*argsand**kwargsin the wrapper, which breaks functions with parameters. - Confusing the decorator with arguments syntax
@decorator(args)with a simple decorator@decorator.
Always ensure the outer function returns the decorator, and the decorator returns the wrapper.
python
def wrong_decorator(times): def decorator(func): def wrapper(): for _ in range(times): func() # Missing return wrapper here causes error return wrapper return decorator # Correct version: def correct_decorator(times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(times): func(*args, **kwargs) return wrapper return decorator
Quick Reference
Remember these points when creating decorators with arguments:
- Use three nested functions: outer (args), decorator (func), wrapper (*args, **kwargs).
- Return the wrapper function from the decorator.
- Use
*argsand**kwargsin wrapper to support any function signature. - Apply with
@decorator(args)syntax.
Key Takeaways
A decorator with arguments uses three nested functions: outer, decorator, and wrapper.
Always return the wrapper function from the decorator to properly wrap the target function.
Use *args and **kwargs in the wrapper to handle any function parameters.
Apply the decorator with arguments using @decorator(args) syntax.
Common errors include missing returns and incorrect wrapper signatures.