重要的 Python 装饰器2024 年 08 月 29 日 | 阅读 9 分钟 在本教程中,我们将学习一些每个 Python 开发人员都应该知道的惊人 Python 装饰器。这些装饰器将帮助将代码提升到一个新的水平,并用更少的代码完成更多的事情。 众所周知,Python 装饰器是一个强大的工具,有助于编写可扩展和干净的代码。为了理解本教程,应该熟悉装饰器。如果您不熟悉装饰器,下面是装饰器的简要介绍。 在 Python 中,装饰器是一种特殊类型的函数,可用于修改另一个函数或类的行为。装饰器接收一个函数或类作为输入,对其执行一些修改,并返回修改后的函数或类。 装饰器由 @ 符号后跟装饰器函数的名称表示,并紧密放置在要装饰的函数或类之前。当调用被装饰的函数或类时,装饰器函数首先执行,其结果用作新的函数或类。 示例 -输出 7 现在,我们将看到重要 Python 装饰器的列表。 1. @loggerlogger 是一个函数,它接受一个函数作为参数并返回一个函数作为输出。输出根据装饰器逻辑进行修改。在本节中,我们将创建 logger 装饰器。由于我们不知道函数输入,我们将传递 *arg 和 **kwarg。*arg 和 **kwarg 参数允许我们传递任意数量的位置参数和关键字参数。让我们看看 logger 装饰器的以下实现。 示例 - 我们可以将上述装饰器应用于任何函数并修改其结果。 decorator_function = logger(function_argument) 我们也可以使用 @ 符号应用装饰器。让我们看下面的例子。 输出 ----- get_text: Function start ----- The Decorator is called ----- get_text: Function end ----- 2. @lru_cache它随 Python functools 模块提供,我们可以导入它。它使用最近最少使用 (LRU) 算法返回函数的值。如果缓存已满,它会丢弃最少使用的值。此装饰器在长时间运行的任务中非常有用,这些任务在相同输入下不会更改输出,例如请求静态页面、删除网页或查询数据库。以下是 @lru_decorator 的示例。 示例 - 解释 - 要从头开始创建缓存装饰器,我们将首先向包装函数添加一个字典作为属性。此字典将用作存储输入函数返回的先前计算值的位置。 当调用输入函数时,装饰器将首先检查传递给函数的参数是否已计算并存储在缓存中;如果已存储,装饰器将返回缓存的结果。否则,装饰器将计算结果并将其添加到缓存中以备将来使用。 3. @repeatrepeat 装饰器负责多次重复。它有助于调试、压力测试或自动化多个任务的重复。让我们理解以下示例 - 示例 - 在上面的代码中,我们定义了一个名为 repeat 的装饰器,它接受多个参数。我们导入了 wraps 装饰器,它包裹在被装饰的函数周围。包装函数以等于指定次数的次数调用被装饰的函数。 输出 Hi, There Hi, There Hi, There Hi, There Hi, There Hi, There Hi, There Hi, There Hi, There Hi, There 4. @timeit此装饰器计算函数的执行时间并打印结果。它可用于调试或监控。让我们理解以下示例。 示例 - 输出 process_data took 1.003516 seconds to complete 5. @retryPython 中的 @retry 装饰器是一个有用的工具,用于在函数由于某些异常而失败时自动重试该函数。此装饰器可以应用于任何函数,并且可以自定义以根据导致失败的异常类型使用不同的参数重试该函数。 以下是如何在 Python 中使用 @retry 装饰器的示例。 示例 - 解释 - 在此示例中,my_function() 函数将重试最多 3 次,每次重试之间有 2 秒的延迟。backoff 参数指定每次重试后延迟将加倍,jitter 参数指定每次重试之间的延迟将在 1 到 3 秒之间随机变化,以避免重试风暴。 默认情况下,如果引发任何异常,@retry 装饰器将重试该函数。但是,您可以通过传递 retry_on_exception 参数来指定要重试的异常列表。 在上面的代码中,my_function 将仅在引发 ValueError 或 TypeError 时重试。 请注意,@retry 装饰器不是 Python 内置的,需要单独安装。有几个库提供了 @retry 装饰器,例如 retrying 和 tenacity。 7. @wraps此装饰器用于保留原始函数的名称文档字符串。让我们理解以下示例。 示例 - 解释 - 在上面的代码中,我们使用 @wraps 装饰器来保留原始 add_numbers() 函数的名称和文档字符串。如果没有 @wraps,被装饰的函数将具有不同的名称和文档字符串,这可能会令人困惑并使调试更加困难。 以下是如何使用 add_numbers 函数的示例。 示例 - 输出 3 add_number This function adds two numbers 7. @rate_limited@rate_limited 装饰器用于限制函数的调用速率,如果函数调用过于频繁,则会休眠一段时间。 示例 - 解释 - 在上面的代码中,我们使用 rate_limited 装饰器来限制函数的调用速率。max_per_second 参数指定函数每秒可以调用的最大次数。 decorate 函数在 rate_limited 装饰器内部定义,用于将原始函数包装到限速逻辑中。我们使用一个列表 last_time_called 来存储函数上次调用的时间,它允许我们在 rate_limited_function 内部更新上次调用时间,即使 last_time_called 是一个可变对象。 rate_limited_function 包装原始函数并计算自上次调用函数以来经过的时间。如果经过的时间小于最小间隔,则函数休眠最小间隔与经过时间之间的差值。然后更新上次调用时间,并使用提供的参数调用原始函数。 输出 Hello, world! Hello, world! Hello, world! Hello, world! Hello, world 在上面的代码中,my_function() 函数被限速为每秒最多调用 2 次。当我们在循环中调用该函数 5 次时,它只打印“Hello, world!”两次,因为限速装饰器在调用之间休眠了适当的时间。 8. @dataclass@dataclass 装饰器用于装饰类。当我们使用 @dataclass 装饰器装饰一个类时,装饰器会根据类属性自动为该类生成几个特殊方法,例如 __init__()、__repr__()、__eq__() 等。这省去了程序员手动定义这些方法的精力,这可能很繁琐且容易出错,尤其是对于具有许多属性的类。它还提供了现成的精妙方法来很好地表示对象,将它们转换为 JSON 格式,使它们不可变等。 此装饰器在 Python 3.7 中引入,并可在标准库中使用。 让我们理解下面的例子。 示例 - 输出 Car(make='Honda', model='Civic', year=2022, price=25000.0) Car(make='Toyota', model='Corolla', year=2022, price=24000.0) False 解释 - 在上面的代码中,我们定义了一个 Car 类,它有四个属性:make、model、year 和 price。@dataclass 装饰器自动为该类生成几个特殊方法,包括一个以四个属性作为参数的 __init__() 方法,一个返回对象字符串表示的 __repr__() 方法,以及一个根据其属性比较两个对象的 __eq__() 方法。 然后我们创建 Car 类的两个实例 car1 和 car2,并将它们打印到控制台。最后,我们使用 == 运算符比较 car1 和 car2,它调用 @dataclass 装饰器生成的 __eq__() 方法。 9. @singledispatch@singledispatch 装饰器是 Python functools 模块中的一个函数装饰器,它定义了一个泛型函数,该函数根据其参数类型表现不同。它提供了一种在 Python 中实现多态行为的简单方法。 下面是 @singledispatch 装饰器如何使用的示例。 示例 - from functools import singledispatch 输出 This is an integer: 42 This is a string: hello Unknown type argument 解释 - 在上面的代码中,我们使用 @singledispatch 装饰器定义了一个名为 myfunc 的泛型函数。该函数最初定义为在调用任何参数类型时打印泛型消息。 然后我们使用 register() 方法为 int 和 str 类型定义 myfunc 的特定实现。_ 标识符用于指示函数不使用该参数。 10. @register@register 装饰器在 Python 脚本意外终止但我们仍希望在退出前执行某些操作的情况下非常有用。使用 @register 装饰器注册函数可确保即使发生错误,该函数也会在脚本退出之前调用。 例如,我们可以使用 @register 装饰器注册一个清理函数,该函数在脚本终止前保存我们的工作或打印消息。它在长时间运行的脚本或执行重要任务的脚本中特别有用。 @register 装饰器提供了一种简单灵活的方式,无论终止原因如何,都可以在脚本退出前执行操作。 结论装饰器是强大的工具,可以通过添加缓存、日志记录、限速和自动重试等新功能来增强代码。它们还可以用于将类转换为更通用的数据容器。 通过利用装饰器的强大功能,您可以使代码更模块化、更高效、更灵活。无论您是从事大型项目还是小型个人脚本,装饰器都可以帮助您将代码提升到一个新的水平。 |
在本教程中,我们将学习如何将 tqdm 与 pandas 库一起实现。tqdm 模块用于根据需要创建进程条。进程条是估算和显示任务所需时间的重要工具。要理解...
5 分钟阅读
在下面的教程中,我们将创建一个 Python 程序来估计买卖股票的最佳时间。那么,让我们开始吧。理解 Python 项目假设我们有一个数组 X,其中 X[i] 表示给定股票在第 n 天的价格。我们需要...
阅读 4 分钟
Bokeh 是一个用于数据可视化的 Python 库。它使用 HTML 和 JavaScript 语言创建其绘图,并且它还针对现代网站浏览器,以提供优雅的演示、新颖图形的简洁构建以及良好的高性能交互性。在本教程中,我们将学习如何...
阅读 3 分钟
基础/先决知识简述:JSON 代表“JavaScript 对象表示法”。它是一种标准的句法样式,用于以文件形式存储和通过网络交换数据(互换)。JSON 的语法只是简单的文本,这使其更高级。它...
阅读 4 分钟
在本教程中,我们将了解 Google 的 Protobuf 以及如何使用 Python 编程语言实现它。假设有一群来自不同起源的人,他们说不同的语言。为了有效沟通,他们尝试使用一种每个人都能理解的语言……
阅读 8 分钟
有很多情况下我们必须获取博客网站甚至有时是浏览器的财务数据或报表。允许我们收集其财务数据的著名浏览器之一是 Yahoo,实际上,在许多情况下我们需要...
阅读 19 分钟
菜单驱动程序简介 菜单驱动程序是一种通过显示选项列表(称为菜单)从用户获取输入的程序,用户从中选择他们的选项。处理菜单驱动程序的系统很常见,从微处理器控制的洗衣机到...
阅读 12 分钟
数据分析是一种有效的技术,支持企业决策。在今天的教程中,我们将使用 Python 调查 Netflix 信息集并发现有趣的结果。Netflix 是全球最大和最受欢迎的在线服务之一,为客户提供庞大的电视节目库...
11 分钟阅读
在本教程中,我们将学习如何使用 Matplotlib 在子图中包含图例。创建图后可以使用 legend() 函数添加图例。语法:子图中图例的语法是:axes[position].legend(loc = ''),其中 loc 用于位置。方法:以下是我们将介绍的方法...
阅读 3 分钟
在 Python 中,浮点值的范围取决于实现和平台。Python 语言规范仅要求浮点数至少支持 1e-308 到 1e+308,精度至少为 53 位。实际上,大多数现代 Python 实现都使用 IEEE 754...
阅读 4 分钟
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India