Python装饰器实战:5个高级应用场景
1. 基础函数装饰器
实现简单的日志记录装饰器:
def log_execution(func):
def wrapper(*args, **kwargs):
print(f"开始执行: {func.__name__}")
result = func(*args, **kwargs)
print(f"执行完成: {func.__name__}")
return result
return wrapper
@log_execution
def calculate_sum(a, b):
return a + b
# 使用
result = calculate_sum(3, 5)
print(f"结果: {result}")
2. 带参数的装饰器
创建可配置的重试机制:
def retry(max_attempts=3, delay=1):
def decorator(func):
import time
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
print(f"尝试 {attempts} 失败: {e}")
if attempts == max_attempts:
raise
time.sleep(delay)
return wrapper
return decorator
@retry(max_attempts=5, delay=2)
def fetch_data(url):
# 模拟可能失败的请求
if "example" not in url:
raise ValueError("无效的URL")
return "数据内容"
3. 类装饰器
为类添加单例模式:
def singleton(cls):
instances = {}
def wrapper(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class DatabaseConnection:
def __init__(self):
print("创建新的数据库连接")
# 使用
conn1 = DatabaseConnection()
conn2 = DatabaseConnection()
print(conn1 is conn2) # 输出: True
4. 方法装饰器
实现属性缓存:
def cached_property(func):
@property
def wrapper(self):
cache_attr = f"_cached_{func.__name__}"
if not hasattr(self, cache_attr):
setattr(self, cache_attr, func(self))
return getattr(self, cache_attr)
return wrapper
class DataProcessor:
@cached_property
def processed_data(self):
print("执行耗时计算...")
return [i**2 for i in range(1000000)]
装饰器类型 | 适用场景 | 优势 |
---|---|---|
函数装饰器 | 函数增强 | 简单灵活 |
类装饰器 | 类改造 | 功能强大 |
方法装饰器 | 类方法处理 | 面向对象 |
5. 装饰器组合与顺序
多个装饰器的堆叠使用:
def validate_input(func):
def wrapper(a, b):
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
raise ValueError("参数必须是数字")
return func(a, b)
return wrapper
def log_arguments(func):
def wrapper(a, b):
print(f"调用参数: a={a}, b={b}")
return func(a, b)
return wrapper
@validate_input
@log_arguments
def divide(a, b):
return a / b
# 使用
result = divide(10, 2) # 先验证参数,再记录日志
合理使用装饰器可以大幅提升Python代码的可维护性和复用性,是Python高级开发者的必备技能。