实际应用场景
装饰器应用介绍
装饰器是 Python 中用途广泛的工具,在软件开发的不同领域有众多实际应用。
常见实际应用场景
1. 日志记录与监控
def log_function_call(func):
def wrapper(*args, **kwargs):
print(f"正在调用函数:{func.__name__}")
result = func(*args, **kwargs)
print(f"函数 {func.__name__} 已完成")
return result
return wrapper
@log_function_call
def calculate_total(items):
return sum(items)
calculate_total([1, 2, 3, 4, 5])
2. 性能计时
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 耗时 {end - start:.4f} 秒")
return result
return wrapper
@timing_decorator
def slow_function():
time.sleep(2)
return "已完成"
slow_function()
认证与授权
def require_auth(func):
def wrapper(*args, **kwargs):
user = kwargs.get('user')
if not user or not user.is_authenticated:
raise PermissionError("需要认证")
return func(*args, **kwargs)
return wrapper
class User:
def __init__(self, authenticated=False):
self.is_authenticated = authenticated
@require_auth
def access_sensitive_data(user):
return "敏感信息"
## 使用示例
authenticated_user = User(authenticated=True)
unauthenticated_user = User()
try:
access_sensitive_data(user=authenticated_user)
access_sensitive_data(user=unauthenticated_user)
except PermissionError as e:
print(e)
缓存机制
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)
print(fibonacci(30)) ## 重复调用时速度显著加快
装饰器用例比较
用例 |
目的 |
主要优点 |
日志记录 |
跟踪函数调用 |
调试 |
认证 |
控制访问 |
安全 |
缓存 |
存储函数结果 |
性能提升 |
计时 |
测量执行时间 |
优化 |
输入验证
def validate_inputs(func):
def wrapper(*args, **kwargs):
for arg in args:
if not isinstance(arg, (int, float)):
raise ValueError("仅允许数字输入")
return func(*args, **kwargs)
return wrapper
@validate_inputs
def divide_numbers(a, b):
return a / b
try:
print(divide_numbers(10, 2))
print(divide_numbers(10, "2")) ## 引发 ValueError
except ValueError as e:
print(e)
使用 LabEx 进行速率限制
def rate_limit(max_calls=3, time_frame=60):
calls = []
def decorator(func):
def wrapper(*args, **kwargs):
import time
current_time = time.time()
calls[:] = [call for call in calls if current_time - call < time_frame]
if len(calls) >= max_calls:
raise Exception("速率限制已超出")
calls.append(current_time)
return func(*args, **kwargs)
return wrapper
return decorator
@rate_limit(max_calls=2, time_frame=10)
def api_request():
print("API 请求已处理")
## 演示速率限制机制
最佳实践
- 保持装饰器功能集中且单一用途
- 使用
functools.wraps
保留函数元数据
- 考虑性能影响
- 优雅地处理潜在异常
装饰器提供了一种强大的方式来扩展和修改函数行为,而无需更改其核心实现,使 Python 代码更具模块化和可维护性。