Tuesday, August 26, 2025

🐍COMMON MISTAKES WITH DECORATORS

Common Mistakes & Gotchas with Decorators

Decorators are powerful, but beginners often make mistakes that lead to confusing errors. Let’s look at the most common pitfalls and how to avoid them.

1. Forgetting to Return the Wrapper

A decorator must return the wrapper function. If you forget the return, the decorated function becomes None.


def bad_decorator(func):
    def wrapper(*args, **kwargs):
        print("Doing something...")
        func(*args, **kwargs)
    # Missing "return wrapper" here!

@bad_decorator
def greet(name):
    print(f"Hello, {name}!")

print(greet)   # Output: None 😢

2. Losing Function Metadata

Without @wraps, the decorated function loses its original name and docstring. This is problematic for debugging and documentation tools.


def my_decorator(func):
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def greet():
    """This function says hello."""
    print("Hello!")

print(greet.__name__)   # wrapper ❌
print(greet.__doc__)    # None ❌

Fix: Use functools.wraps(func) to preserve metadata.

3. Over-Decorating Functions

Applying too many decorators can make code hard to read and debug. Keep decorators focused on one responsibility.


@decorator_one
@decorator_two
@decorator_three
def some_function():
    pass

✔️ Keep it simple. Chain only when necessary.

4. Forgetting Arguments

If your function requires arguments but your wrapper doesn’t accept them, you’ll get an error.


def my_decorator(func):
    def wrapper():   # ❌ Forgot *args, **kwargs
        print("Before...")
        func()       # ❌ This will fail if arguments exist
    return wrapper

@my_decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")   # TypeError ❌

Fix: Always include *args and **kwargs in the wrapper.

5. Decorators Running Too Early

Remember that decorators are executed at function definition time, not when the function is called.


def announce(func):
    print("Decorator is running!")  # Runs immediately
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@announce
def greet():
    print("Hello!")

# Output when script runs:
# Decorator is running! ✅

This can surprise beginners. It’s normal behavior.

Summary

  • Always return the wrapper from your decorator.
  • Use functools.wraps to keep function name and docstring.
  • Don’t overuse decorators — keep them clean and focused.
  • Always handle *args and **kwargs properly.
  • Remember decorators execute at definition time, not runtime.

🖥️ Practice in Browser

No comments:

Post a Comment

🐍What is scikitlearn??