带参数的装饰器(三层嵌套结构)
python
def repeat_execution(n_times):
# 第一层:接收装饰器参数
def decorator(func):
# 第二层:接收被装饰函数
def wrapper(*args, **kwargs):
# 第三层:执行装饰逻辑
for _ in range(n_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat_execution(n_times=3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
输出:
Hello, Alice!
Hello, Alice!
Hello, Alice!
深度解析:装饰器参数如何传递
@repeat_execution(n_times=3)
首先执行- 调用
repeat_execution(3)
返回decorator
函数
- 调用
- 接着执行
@decorator
- 将
say_hello
作为参数传递给decorator
- 将
- 最终生成装饰后的
wrapper
函数
带状态记录的装饰器
python
def log_performance(metric_name):
def decorator(func):
func.call_count = 0 # 添加函数属性
def wrapper(*args, **kwargs):
func.call_count += 1
print(f"[{metric_name}] 执行 #{func.call_count}")
return func(*args, **kwargs)
return wrapper
return decorator
@log_performance("用户验证")
def authenticate(user):
return user == "admin"
print(authenticate("guest"))
print(authenticate("admin"))
print(f"验证函数调用次数: {authenticate.call_count}")
输出:
ini
[用户验证] 执行 #1
False
[用户验证] 执行 #2
True
验证函数调用次数: 2
类实现的装饰器参数
python
class TimeoutRetry:
def __init__(self, retries=3, delay=1):
self.retries = retries
self.delay = delay
def __call__(self, func):
import time
def wrapper(*args, **kwargs):
for attempt in range(self.retries):
try:
return func(*args, **kwargs)
except TimeoutError:
print(f"超时重试中... ({attempt+1}/{self.retries})")
time.sleep(self.delay)
raise Exception("所有重试均失败")
return wrapper
@TimeoutRetry(retries=2, delay=0.5)
def fetch_data():
# 模拟网络请求
raise TimeoutError("连接超时")
fetch_data() # 将触发重试机制
装饰器参数的最佳实践
-
命名规范 :使用描述性的参数名(如
max_retries
而非n
) -
参数验证 :在装饰器最外层验证参数有效性
pythondef validate_params(max_time): if max_time <= 0: raise ValueError("最大时间必须为正数")
-
保留元数据 :使用
@functools.wraps
保持原始函数属性pythonfrom functools import wraps def debug_decorator(level): def decorator(func): @wraps(func) # 保留原始函数信息 def wrapper(*args, **kwargs): if level > 1: print(f"[DEBUG] 调用 {func.__name__}") return func(*args, **kwargs) return wrapper return decorator