Decorators in Python are a powerful tool that allows you to modify or extend the behavior of functions or classes without changing their source code. They're often used for tasks like logging, access control, and memoization. Let's dive into the essentials!

📌 Basic Syntax

A decorator is a function that wraps another function. Here's a simple example:

def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

When say_hello() is called, it will execute the wrapper() function instead.

🧠 Advanced Concepts

  • Nested Decorators: Apply multiple decorators to a single function
    @decorator1
    @decorator2
    def my_function():
        pass
    
  • Class Decorators: Modify class behavior
    def decorator(cls):
        cls.new_attr = "Added by decorator"
        return cls
    

@decorator class MyClass: pass

- **Parameterized Decorators**: Pass arguments to decorators  
```python
def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def greet(name):
  print(f"Hello {name}")

📚 Use Cases

  • Adding logging: <center><img src="https://cloud-image.ullrai.com/q/python_decorator_logging/" alt="python_decorator_logging"/></center>
  • Implementing caching: <center><img src="https://cloud-image.ullrai.com/q/python_decorator_caching/" alt="python_decorator_caching"/></center>
  • Validating inputs: <center><img src="https://cloud-image.ullrai.com/q/python_decorator_validation/" alt="python_decorator_validation"/></center>
  • Timing function execution: <center><img src="https://cloud-image.ullrai.com/q/python_decorator_timing/" alt="python_decorator_timing"/></center>

⚠️ Best Practices

  1. Avoid overcomplicating simple tasks
  2. Use functools.wraps to preserve metadata
  3. Be mindful of decorator order (innermost first)
  4. Consider performance impacts for frequent calls

For deeper exploration, check our Python Functions Guide to understand how decorators interact with function definitions.

python_decorator_flowchart