Understanding Python Decorators
Decorators are one of Python's most elegant features. They allow you to modify the behavior of functions or classes without changing their source code.
What are Decorators?
A decorator is a function that takes another function and extends its behavior without explicitly modifying it. It's essentially a wrapper function.
Basic Decorator Syntax
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Common Use Cases
1. Timing Functions
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} took {end - start} seconds")
return result
return wrapper
2. Caching
from functools import lru_cache
@lru_cache(maxsize=128)
def expensive_function(n):
# Expensive computation
return n * n
3. Authentication
def require_auth(func):
def wrapper(*args, **kwargs):
if not is_authenticated():
raise PermissionError("Authentication required")
return func(*args, **kwargs)
return wrapper
Class Decorators
You can also use decorators with classes:
def add_method(cls):
def new_method(self):
return "New method added!"
cls.new_method = new_method
return cls
@add_method
class MyClass:
pass
Best Practices
- Use
functools.wrapsto preserve function metadata - Keep decorators simple and focused
- Document what your decorator does
- Consider using decorator factories for parameterized decorators
Decorators are a powerful tool that can make your code more elegant and maintainable.