当前位置:首页 > Python > 正文内容

Python 装饰器完全指南:从入门到实战

admin2个月前 (03-19)Python85

装饰器本质上是一个接受函数作为参数并返回新函数的高阶函数。理解这一点是掌握装饰器的关键。想象一下,你有一个函数,你想在它执行前后添加一些额外的逻辑,比如日志记录、性能测试、权限验证等。装饰器就是为这种场景而生的。

让我们从一个最简单的例子开始。假设你有一个函数,你想知道它执行了多长时间:

import time
from functools import wraps

def timer_decorator(func):
    """计算函数执行时间的装饰器"""
    @wraps(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:.4f}秒")
        return result
    return wrapper

@timer_decorator
def slow_function():
    time.sleep(1)
    return "完成"

slow_function()

这个例子展示了装饰器的基本结构。@wraps 是一个重要的细节,它保留了原函数的元数据(如函数名、文档字符串等),否则调试时会看到 wrapper 而不是原函数名。

接下来,让我们看看带参数的装饰器。这种装饰器更加灵活,可以接受配置参数:

def retry(max_attempts=3, delay=1):
    """失败后自动重试的装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            attempts = 0
            while attempts < max_attempts:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    attempts += 1
                    if attempts >= max_attempts:
                        raise
                    print(f"重试 {attempts}/{max_attempts}, 等待 {delay}秒...")
                    time.sleep(delay)
        return wrapper
    return decorator

@retry(max_attempts=5, delay=0.5)
def unstable_operation():
    import random
    if random.random() < 0.7:
        raise ConnectionError("网络不稳定")
    return "操作成功"

带参数的装饰器需要三层嵌套:最外层接收装饰器参数,中间层接收被装饰的函数,最内层是实际执行的 wrapper。这种模式在实际开发中非常常见。

装饰器不仅可以用于函数,还可以用于类方法。这在 Web 开发中特别有用,比如实现权限检查。我们可以堆叠多个装饰器,装饰器的执行顺序是从下往上的。

类装饰器是另一个强大的工具,它允许你修改整个类的行为,比如实现单例模式。在实际项目中,装饰器有着广泛的应用,包括缓存装饰器避免重复计算、日志装饰器记录函数调用、速率限制装饰器防止 API 被滥用等。

编写装饰器时有一些最佳实践需要注意:始终使用 @wraps 来保留原函数的元数据;让装饰器接受 *args 和 **kwargs;保持装饰器的单一职责;考虑装饰器的性能影响。

装饰器是 Python 优雅性的体现之一。它让你能够以声明式的方式添加功能,使代码更加简洁和可维护。掌握装饰器后,你会发现很多原本需要重复编写的代码可以用几行装饰器来解决。

相关文章

[Python 教程] OpenCV 绘图教程:图形与文本标注

OpenCV 绘图教程:图形与文本标注本文介绍如何在 OpenCV 中绘制各种图形和添加文本,用于图像标注和可视化。一、绘制基本图形1.1 创建画布import cv2 import&nb...

[Python 教程] Matplotlib 数据可视化教程

Matplotlib 数据可视化教程 Matplotlib 是 Python 最常用的绘图库。本文介绍常用图表的绘制方法。 一、基础设置 import matplotlib.pyplot as pl...

深入理解 Python 上下文管理器:从基础到高级应用

Python 的 with 语句和上下文管理器是每个开发者都应该掌握的高级技巧,但很多初学者对它的理解仅仅停留在文件操作层面。本文将深入讲解上下文管理器的原理、多种实现方式,以及在实际开发中的高级应用...

Python 生成器进阶:理解 yield 与构建高效迭代器

在 Python 开发中,我们经常需要处理大量数据或流式数据,如果一次性将所有数据加载到内存中,不仅会占用大量内存空间,还可能导致程序运行缓慢甚至崩溃。生成器(Generator)正是解决这个问题的利...

Python 异步编程实战:从入门到精通

在 Python 开发中,我们经常会遇到需要同时处理多个 I/O 操作的场景。比如同时向多个 API 发送请求、批量下载文件、或者处理实时数据流。传统的同步方式会阻塞主线程,导致性能瓶颈。而异步编程通...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。