Python’s decorators and context managers are powerful tools that enhance code readability, maintainability, and functionality. In this article, we’ll delve into advanced techniques for decorators, exploring real-world examples and their outputs.
Understanding Advanced Decorators:
Decorators in Python are functions that modify the behavior of other functions or methods. They provide a convenient way to add functionality to existing code without modifying its structure. Let’s explore some advanced decorator techniques:
1. Class-based Decorators:
In addition to function-based decorators, Python supports class-based decorators. Class-based decorators provide more flexibility and allow for additional state management. Consider the following example:
class Logger:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f"Calling {self.func.__name__}")
return self.func(*args, **kwargs)
@Logger
def add(a, b):
return a + b
result = add(2, 3)
print("Result:", result)
Output:
Calling add
Result: 5
In this example, the Logger
class acts as a decorator, adding logging functionality to the add
function.
2. Decorator Factories:
Decorator factories are functions that return decorators based on input parameters. This enables dynamic behavior customization. Let’s see an example:
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}!")
greet("Alice")
Output:
Hello, Alice!
Hello, Alice!
Hello, Alice!
Real-world Example: Performance Monitoring Decorator
Let’s create a decorator that monitors the performance of a function by measuring its execution time:
import time
def performance_monitor(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} seconds")
return result
return wrapper
@performance_monitor
def calculate_sum(n):
return sum(range(n))
result = calculate_sum(1000000)
print("Sum:", result)
Output:
calculate_sum executed in 0.036206960678100586 seconds
Sum: 499999500000