当前位置: 首页 > news >正文

Python实用装饰器提升开发效率

Python实用装饰器提升开发效率

装饰器是 Python 中一项强大而灵活的功能,它允许我们在不修改原始代码的情况下,为函数或类添加额外的功能。无论是性能优化、调试辅助还是代码健壮性提升,装饰器都能让我们的开发工作事半功倍。

下面分享 10 个简单但超级有用的自定义装饰器,每一个都配有完整的代码实现和使用示例。

1. @timer - 测量函数执行时间

优化代码性能时,了解函数的执行时间至关重要。@timer 装饰器可以轻松跟踪函数的运行时长:

import timedef 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:.2f} 秒")return resultreturn 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] = resultprint(f"计算并缓存结果: {args} -> {result}")return resultreturn wrapper@memoize
def fibonacci(n):if n <= 1:return nreturn 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)):if not isinstance(arg, expected_type):raise TypeError(f"参数 {i} 应该是 {expected_type} 类型,但得到的是 {type(arg)}")return func(*args, **kwargs)return wrapperreturn decorator@validate_input(list, int)
def get_list_slice(data, n):"""获取列表的前n个元素"""return data[:n]# 使用示例
try:result = get_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 resultreturn wrapperreturn decorator@log_results("calculations.log")
def calculate_statistics(numbers):"""计算数据的统计信息"""if not numbers:return Nonereturn {'sum': sum(numbers),'mean': sum(numbers) / len(numbers),'max': max(numbers),'min': min(numbers)}# 使用示例
stats = calculate_statistics([10, 20, 30, 40, 50])
print(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_returnreturn wrapperreturn 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 resultelse:raise ValueError(f"函数 {func.__name__} 的输出未通过验证: {result}")return wrapperreturn decoratordef 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 randomdef retry(max_attempts=3, delay=1, backoff=2):def decorator(func):def wrapper(*args, **kwargs):attempts = 0current_delay = delaywhile attempts < max_attempts:try:return func(*args, **kwargs)except Exception as e:attempts += 1if attempts == max_attempts:raise Exception(f"超过最大重试次数 ({max_attempts}),最后错误: {e}")print(f"第 {attempts} 次尝试失败,{current_delay} 秒后重试... 错误: {e}")time.sleep(current_delay)current_delay *= backoff  # 指数退避return wrapperreturn 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)if verbose:print(f"   返回值: {result}")print(f"✅ {func.__name__} 执行完成\n")return resultreturn wrapperreturn decorator@debug(verbose=True)
def complex_calculation(a, b, coefficient=1.5):"""执行复杂计算"""intermediate = (a ** 2 + b ** 2) ** 0.5return intermediate * coefficient# 使用示例
result = complex_calculation(3, 4, coefficient=2)

9. @deprecated - 标记过时函数

当函数不再推荐使用时,向用户发出警告:

import warningsdef 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 wrapperreturn 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 pltdef 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 resultreturn wrapperreturn 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 可以保留原函数的元信息
  • 装饰器也可以接受参数,实现更灵活的功能配置
http://www.dtcms.com/a/539978.html

相关文章:

  • 【JAVA 进阶】Mybatis-Plus 实战使用与最佳实践
  • LangGraph 官方教程:聊天机器人之五
  • 天硕工业SSD揭秘无DRAM缓存SSD的性能差距
  • C# 内存是绝对自动清理吗?
  • 在 CentOS 系统上实现定时执行 Python 邮件发送任务完整指南
  • C#操作Excel
  • 放置在网站根目录下中国做外贸最好的网站有哪些
  • 二叉搜索树,咕咕咕
  • 可用 Docker (DockerHub) 国内镜像源加速列表 - 长期维护(截至 2025 年 06 月 15 日)
  • QtQuick3D入门(5):实例化渲染
  • 浙人医基于金仓 KFS 工具信创落地:多数据库协同难题解决方案详讲
  • [C++STL] :list的简介和使用
  • Nacos配置中心实战进阶:多场景动态刷新全解析
  • Linux写sh开机启动脚本-bash报错的两种解决方法
  • 注册协议通知
  • wordpress网站部署百度一下一下你就知道
  • 健康濮阳门户网站建设装企erp管理系统
  • C++ stack和queue之OJ题目
  • 【网络】在windows下,使用自带的ftp服务器,并添加账户
  • 基于python大数据的网络新闻可视化及分析系统
  • 6.1.1.3 大数据方法论与实践指南-SparkStreaming 任务优化实践
  • uniapp实现PDF的预览
  • 推送远程git仓库报错:内部服务错误
  • Qt 6以上版本都试用 连接 MySQL 数据库全流程(CMake 环境)
  • 使用 C# 打印 PDF 文档:基于 Spire.PDF 的实战教程
  • 数据库--JDBC编程
  • 开源一个基于OpenCV的模糊检测工具,支持局部分析和视频处理
  • 政协网站建设情况汇报为什么wordpress安装成了英文版
  • 不做网站只做推广可以么襄阳网站建设首选公司哪家好
  • 10月28日