Python中十个常用的自定义装饰器的使用详解
目录
- 1. @timer - 测量函数执行时间
- 2. @memoize - 缓存函数结果
- 3. @validate_input - 参数验证
- 4. @log_results - 记录函数输出
- 5. @suppress_errors - 优雅的错误处理
- 6. @validate_output - 输出验证
- 7. @retry - 自动重试机制
- 8. @debug - 调试助手
- 9. @deprecated - 标记过时函数
- 10. @visualize_results - 自动可视化
- 总结
装饰器是 python 中一项强大而灵活的功能,它允许我们在不修改原始代码的情况下,为函数或类添加额外的功能。无论是性能优化、调试辅助还是代码健壮性提升,装饰器都能让我们的开发工作事半功倍。
下面分享 10 个简单但超级有用的自定义装饰器,每一个都配有完整的代码实现和使用示例。
1. @timer - 测量函数执行时间
优化代码性能时,了解函数的执行时间至关重要。@timer 装饰器可以轻松跟踪函数的运行时长:
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} 执行耗时: {end_time - start_time:.2phpf} 秒")
return result
return wrapper
@timer
def process_large_dataset():
"""模拟处理大型数据集"""
data = [x ** 2 for x in range(1000000)]
return sum(data)
# 使用示例
result = process_large_dataset()
print(f"处理结果: {result}")
2. @memoize - 缓存函数结果
对于计算成本高的函数,@memoize 可以缓存结果,避免相同输入的重复计算:
def memoize(func):
cache = {}
def wrapper(*args):
if args in cache:
print(f"从缓存中获取结果: {args} -> {cache[args]}")
return cache[args]
result = func(*args)
cache[args] = result
print(f"计算并缓存结果: {args} -> {result}")
return result
return wrapper
@memoize
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# 使用示例
print(fibonacci(10)) # 第一次计算
print(fibonacci(10)) # 从缓存获取
3. @validate_input - 参数验证
确保函数接收到的参数符合预期标准:
def validate_input(*expected_types):
def decorator(func):
def wrapper(*args, **kwargs):
for i, (arg, expected_type) in enumerate(zip(args, expected_types)):
http://www.devze.com if not isinstance(arg, expected_type):
raise TypeError(f"参数 {i} 应该是 {expected_type} 类型,但得到的是 {type(arg)}")
return func(*args, **kwargs)
return wrapper
return decorator
@validate_input(list, int)
def get_list_slice(data, n):
"""获取列表的前n个元素"""
return data[:n]
# 使用示例
try:
result = www.devze.comget_list_slice([1, 2, 3, 4, 5], 3)
print(f"切片结果: {result}")
get_list_slice("不是列表", 3) # 这会抛出异常
except TypeError as e:
print(f"错误: {e}")
4. @log_results - 记录函数输出
在复杂的数据分析任务中,记录函数结果对于调试和监控非常有帮助:
def log_results(log_file="function_results.log"):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
with open(log_file, "a", encoding="utf-8") as f:
f.write(f"{func.__name__} - 参数: {args} {kwargs} - 结果: {result}\n")
return result
return wrapper
return decorator
@log_results("calculations.log")
def calculate_statistics(numbers):
"""计算数据的统计信息"""
if not numbers:
return None
return {
'sum': sum(numbers),
'mean': sum(numbers) / len(numbers),
'max': max(numbers),
'min': min(numbers)
}
# 使用示例
stats = calculate_statistics([10, 20, 30, 40, 50])
printandroid(f"统计结果: {stats}")
5. @suppress_errors - 优雅的错误处理
防止意外错误中断整个执行流程:
def suppress_errors(default_return=None):
def decorator(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"函数 {func.__name__} 执行出错: {e}")
return default_return
return wrapper
return decorator
@suppress_errors(default_return=0)
def safe_divide(a, b):
"""安全的除法运算"""
return a / b
# 使用示例
print(f"10 / 2 = {safe_divide(10, 2)}")
print(f"10 / 0 = {safe_divide(10, 0)}") # 不会崩溃,返回默认值0
6. @validate_output - 输出验证
确保函数输出符合质量标准:
def validate_output(validation_func):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
if validation_func(result):
return result
else:
raise ValueError(f"函数 {func.__name__} 的输出未通过验证: {result}")
return wrapper
return decorator
def is_positive_number(x):
"""验证是否为正数"""
return isinstance(x, (int, float)) and x > 0
@validate_output(is_positive_number)
def process_value(x):
"""处理数值,确保返回正数"""
return abs(x) + 1
# 使用示例
try:
print(f"处理 -5: {process_value(-5)}")
print(f"处理 10: {process_value(10)}")
except ValueError as e:
print(f"验证失败: {e}")
7. @retry - 自动重试机制
在网络请求等可能临时失败的操作中自动重试:
import time
import random
def retry(max_attempts=3, delay=1, backoff=2):
def decorator(func):
def wrapper(*args, **kwargs):
attempts = 0
current_delay = delay
while attempts < max_attempts:
try:
return func(*args, **kwargs)
except Exception as e:
attempts += 1
if attempts == max_attempts:
raise Exception(f"超过最大重试次数 ({max_attempts}),最后错误: {e}")
print(f"第 {attempts} 次尝试失败,{current_delay} 秒后重试... 错误: {e}")
time.sleep(current_delay)
current_delay *= backoff # 指数退避
return wrapper
return decorator
@retry(max_attempts=3, delay=1)
def unreliable_operation():
"""模拟可能失败的操作"""
if random.random() < 0.7: # 70% 的失败率
raise Exception("随机失败!")
return "操作成功!"
# 使用示例
try:
result = unreliable_operation()
print(result)
except Exception as e:
print(f"最终失败: {e}")
8. @debug - 调试助手
自动打印函数的输入参数和返回值,简化调试过程:
def debug(verbose=True):
def decorator(func):
def wrapper(*args, **kwargs):
if verbose:
print(f" 调用 {func.__name__}")
print(f" 参数: {args}")
print(f" 关键字参数: {kwargs}")
result = func(*args, **kwargs)php
if verbose:
print(f" 返回值: {result}")
print(f"✅ {func.__name__} 执行完成\n")
return result
return wrapper
return decorator
@debug(verbose=True)
def complex_calculation(a, b, coefficient=1.5):
"""执行复杂计算"""
intermediate = (a ** 2 + b ** 2) ** 0.5
return intermediate * coefficient
# 使用示例
result = complex_calculation(3, 4, coefficient=2)
9. @deprecated - 标记过时函数
当函数不再推荐使用时,向用户发出警告:
import warnings
def deprecated(replacement=None):
def decorator(func):
def wrapper(*args, **kwargs):
message = f"函数 '{func.__name__}' 已过时,将在未来版本中移除。"
if replacement:
message += f" 请使用 '{replacement}' 代替。"
warnings.warn(message, DeprecationWarning, stacklevel=2)
return func(*args, **kwargs)
return wrapper
return decorator
@deprecated(replacement="new_data_processor")
def old_data_processor(data):
"""旧的数据处理函数"""
return [x * 2 for x in data]
def new_data_processor(data):
"""新的数据处理函数"""
return [x ** 2 for x in data]
# 使用示例
data = [1, 2, 3, 4, 5]
result = old_data_processor(data) # 会显示过时警告
print(f"旧方法结果: {result}")
10. @visualize_results - 自动可视化
为数据分析函数自动生成可视化结果:
import matplotlib.pyplot as plt
def visualize_results(title=None):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
# 创建可视化
plt.figure(figsize=(10, 6))
if isinstance(result, (list, tuple)):
plt.plot(result, marker='o', linestyle='-', color='blue')
plt.xlabel('索引')
plt.ylabel('值')
elif isinstance(result, dict):
keys = list(result.keys())
values = list(result.values())
plt.bar(keys, values, color='skyblue')
plt.xlabel('键')
plt.ylabel('值')
plot_title = title or f"{func.__name__} 结果可视化"
plt.title(plot_title)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
return result
return wrapper
return decorator
@visualize_results("月度销售数据趋势")
def analyze_sales_trend():
"""模拟分析销售趋势"""
# 模拟月度销售数据
months = ['1月', '2月', '3月', '4月', '5月', '6月']
sales = [120, 150, 130, 170, 200, 180]
return dict(zip(months, sales))
# 使用示例
sales_data = analyze_sales_trend()
print(f"销售数据: {sales_data}")
总结
这些装饰器展示了 Python 装饰器的强大威力。通过简单的 @ 语法,我们就能为函数添加缓存、日志、验证、重试等复杂功能,而无需修改原始函数代码。
在实际项目中,你可以根据具体需求组合使用这些装饰器,或者创建自己的定制装饰器。掌握装饰器不仅能让你的代码更加简洁优雅,还能显著提升开发效率和代码质量。
使用技巧:
- 多个装饰器可以堆叠使用,执行顺序是从下往上
- 使用
functools.wraps可以保留原函数的元信息 - 装饰器也可以接受参数,实现更灵活的功能配置
以上就是Python中十个常用的自定义装饰器的使用详解的详细内容,更多关于Python自定义装饰器的资料请关注编程客栈(www.devze.com)其它相关文章!
加载中,请稍侯......
精彩评论