Practical Implementation
Real-World Decorator Scenarios
Practical implementation of decorators involves solving common programming challenges with elegant, reusable solutions.
Authentication Decorator
def authenticate(func):
def wrapper(*args, **kwargs):
user = kwargs.get('user')
if not user or not user.is_authenticated():
raise PermissionError("Authentication required")
return func(*args, **kwargs)
return wrapper
class User:
def __init__(self, authenticated=False):
self._authenticated = authenticated
def is_authenticated(self):
return self._authenticated
@authenticate
def access_sensitive_data(user):
return "Confidential Information"
import time
import functools
def measure_performance(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} executed in {end_time - start_time:.4f} seconds")
return result
return wrapper
@measure_performance
def complex_calculation(n):
return sum(i**2 for i in range(n))
Decorator Use Case Comparison
Use Case |
Decorator Benefit |
Implementation Complexity |
Logging |
Low overhead |
Simple |
Authentication |
Security enhancement |
Moderate |
Caching |
Performance optimization |
Complex |
Rate Limiting |
Resource management |
Advanced |
Caching Decorator Implementation
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
Decorator Workflow
graph TD
A[Original Function] --> B[Decorator Wrapper]
B --> C{Condition Check}
C -->|Pass| D[Execute Function]
C -->|Fail| E[Handle Error/Alternative]
D --> F[Return Result]
Best Practices
- Use
functools.wraps
to preserve metadata
- Handle multiple arguments
- Consider performance implications
- Keep decorators focused and single-purpose
Advanced Techniques
- Class method decorators
- Decorators with arguments
- Stacked decorators
LabEx encourages developers to explore decorators as a powerful Python metaprogramming technique for writing clean, modular code.