What Are Decorators?
A decorator is a function that takes another function as input, adds behavior to it, and returns a modified function. They use Python's first-class function support cleanly.
def my_decorator(func):
def wrapper(*args, **kwargs):
print("Before call")
result = func(*args, **kwargs)
print("After call")
return result
return wrapper
@my_decorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
Preserving Metadata with functools.wraps
from functools import wraps
import time
def timing(func):
@wraps(func) # preserves __name__, __doc__
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__} took {time.perf_counter()-start:.3f}s")
return result
return wrapper
@timing
def slow_fn():
time.sleep(0.1)
Decorator Factories (Decorators with Arguments)
def retry(max_attempts=3, exceptions=(Exception,)):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except exceptions as e:
if attempt == max_attempts - 1:
raise
print(f"Attempt {attempt+1} failed: {e}")
return wrapper
return decorator
@retry(max_attempts=3, exceptions=(ConnectionError,))
def fetch_data(url):
...
Real-World Use Cases
- Caching —
@functools.lru_cachememoizes expensive results - Authentication — check JWT before executing a view
- Rate limiting — count calls and enforce limits
- Logging — log function calls and return values automatically
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
Frequently Asked Questions
Can decorators be applied to class methods?
Yes. Use @staticmethod, @classmethod, and @property as examples. Custom decorators work on methods, but wrap carefully to preserve self.
What is the difference between a decorator and a context manager?
Decorators modify behavior on every function call. Context managers manage resources for a single with block. Use @contextlib.contextmanager to write generators as context managers.