0
0
PythonHow-ToBeginner · 3 min read

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 *args and **kwargs in 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 *args and **kwargs in 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.