迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Python >

使用 Python 装饰器重试代码块

作者:迹忆客 最近更新:2023/06/17 浏览次数:

我们可以用装饰器修改一个函数或类来扩展函数的行为,而不用永久地改变它。 本文讨论如何使用重试装饰器修改现有函数而不更改所述函数。

在这种情况下,修改会在给定情况下多次重试函数,其返回值可能与我们想要的不同。


@retry 装饰器的重要性

我们可以使用装饰器来扩展特定函数的行为,我们可以轻松地创建装饰器来修改该函数,即使我们无法访问它或不想更改它。

我们可能经常需要该函数的特定方式,这就是 Python 装饰器的用武之地。所以让我们创建一个简单的函数来展示装饰器的工作原理。

简单的函数 quotient() 接受两个参数并将第一个参数除以第二个参数。

def quotient(a, b):
    return a / b

print(quotient(3, 7))

输出:

0.42857142857142855

但是,如果我们希望除法结果始终是较大的数被除(因此结果将是 2.3333333333333335),我们可以更改代码或使用装饰器。

使用装饰器,我们可以在不更改其代码块的情况下扩展函数的行为。

def improv(func):
    def inner(a, b):
        if a < b:
            a, b = b, a
        return func(a, b)

    return inner

@improv
def quotient(a, b):
    return a / b

print(quotient(3, 7))

输出:

2.3333333333333335

improv() 函数是一个装饰函数,它将 quotient() 函数作为其参数,并包含一个内部函数,该函数采用 quotient() 函数的参数并引入您需要添加的附加功能。

现在,使用装饰器,我们可以在特定函数上添加重试功能,尤其是对于我们无权访问的函数。

重试装饰器在可能存在不可预测的行为或错误的情况下很有用,并且您希望在它们发生时再次重试相同的操作。

一个典型的例子是在 for 循环中处理失败的请求。 在这种情况下,我们可以使用 @retry 装饰器来管理重试该特定请求指定次数。


在 Python 中使用 @retry 重试代码块

对于重试装饰器,有不同的库提供此功能,其中一个库是 retrying 库。

使用它,您可以指定从 Exceptions 到预期返回结果的等待和停止条件。 要安装 retrying 库,我们可以使用 pip 命令,如下所示:

$ pip install retrying

现在,让我们创建一个函数,它随机创建 0 到 10 之间的数字,但当我们遇到数字大于 1 的情况时会引发 ValueError。

import random

def generateRandomly():
    if random.randint(0, 10) > 1:
        raise ValueError("Number generated is greater than one")
    else:
        return "Finally Generated."

print(generateRandomly())

如果此时生成的数字大于 1,代码输出将如下所示。

Traceback (most recent call last):
  File "c:\Users\jiyik\Documents\Python\SFTP\test.py", line 11, in <module>
    print(generateRandomly())
  File "c:\Users\jiyik\Documents\Python\SFTP\test.py", line 6, in generateRandomly
    raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one

我们不能在代码中抛出 ValueError 的情况,因此我们可以引入重试装饰器来重试 generateRandomly() 函数,直到它不引发 ValueError。

import random
from retrying import retry

@retry
def generateRandomly():
    if random.randint(0, 10) > 1:
        raise ValueError("Number generated is greater than one")
    else:
        return "Finally Generated."

print(generateRandomly())

输出:

Finally Generated.

现在,重试装饰器重试随机操作,直到它没有 ValueError,我们只有字符串 Finally Generated..

通过在 if 块中引入 print() 语句,我们可以看到代码重试 generateRandomly() 的次数。

import random
from retrying import retry

@retry
def generateRandomly():
    if random.randint(0, 10) > 1:
        print("1")
        raise ValueError("Number generated is greater than one")
    else:
        return "Finally Generated."

print(generateRandomly())

输出:

1
1
1
1
1
1
1
Finally Generated.

此处为 8,但运行代码时可能会有所不同。 但是,我们不能出现代码一直重试很长时间的情况。 所以,我们有像 stop_max_attempt_number 和 stop_max_delay 这样的参数。

import random
from retrying import retry

@retry(stop_max_attempt_number=5)
def generateRandomly():
    if random.randint(0, 10) > 1:
        print("1")
        raise ValueError("Number generated is greater than one")
    else:
        return "Finally Generated."

print(generateRandomly())

输出:

1
1
1
Finally Generated.

该函数只重试了 5 次,但要么在第 5 次之前成功,返回值 Finally Generated.,要么不成功并抛出 ValueError。

1
1
1
1
1
File "C:\Python310\lib\site-packages\retrying.py", line 247, in get
    six.reraise(self.value[0], self.value[1], self.value[2])
  File "C:\Python310\lib\site-packages\six.py", line 719, in reraise
    raise value
  File "C:\Python310\lib\site-packages\retrying.py", line 200, in call
    attempt = Attempt(fn(*args, **kwargs), attempt_number, False)
  File "c:\Users\jiyik\Documents\Python\SFTP\test.py", line 9, in generateRandomly
    raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one

使用 tenacity 重试 Python 中的代码块

重试库可能有点古怪,不再维护,但坚韧库提供了所有功能,并提供了更多工具。

要安装 tenacity,请使用以下 pip 命令:

pip install tenacity

我们可以在 3 停止尝试来尝试相同的代码。

import random
from tenacity import retry, stop_after_attempt

@retry(stop=stop_after_attempt(3))
def generateRandomly():
    if random.randint(0, 10) > 1:
        print("1")
        raise ValueError("Number generated is greater than one")
    else:
        return "Finally Generated."

print(generateRandomly())

如果在三次尝试时间范围内生成的随机数小于 1,则代码的输出。

1
Finally Generated.
The above exception was the direct cause of the following exception:
1
1
1
Traceback (most recent call last):
  File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 407, in __call__
    result = fn(*args, **kwargs)
  File "c:\Users\jiyik\Documents\Python\SFTP\test.py", line 9, in generateRandomly
    raise ValueError("Number generated is greater than one")
ValueError: Number generated is greater than one

上述异常是以下异常的直接原因:

Traceback (most recent call last):
  File "c:\Users\akinl\Documents\Python\SFTP\test.py", line 14, in <module>
    print(generateRandomly())
  File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 324, in wrapped_f
    return self(f, *args, **kw)
  File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 404, in __call__
    do = self.iter(retry_state=retry_state)
  File "C:\Python310\lib\site-packages\tenacity\__init__.py", line 361, in iter
    raise retry_exc from fut.exception()
tenacity.RetryError: RetryError[<Future at 0x29a75442c20 state=finished raised ValueError>]

上一篇:Python 装饰器顺序

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

Python 装饰器顺序

发布时间:2023/06/17 浏览次数:192 分类:Python

在这篇 Python 文章中,我们将了解什么是装饰器、它们的使用方式以及我们如何利用它们来构建代码。 我们将看到装饰器是如何成为一种强大的工具,可以用来为我们的应用程序添加功能,并且

Python 中的 super参数

发布时间:2023/06/17 浏览次数:158 分类:Python

本文的主题是正确使用 Python 超级参数。 我们还将了解超和继承的概念、使用超参数的适当代码示例以及基类的概念。Python 中的 super 参数 在 Python 中,super 调用另一个类的方法。

将 Kwargs 传递给 Python 中的另一个函数

发布时间:2023/06/17 浏览次数:128 分类:Python

Python 将 kwargs 参数表示为关键字参数,可以在参数名称前使用两个星号传递参数数量。 通过这篇文章,我们寻找 Python 如何将 kwargs 传递给另一个函数。

在 Python 中打印度数符号

发布时间:2023/06/17 浏览次数:191 分类:Python

本篇文章将介绍如何用 Python 编写度数符号。度数符号是表示特定区域温度的符号。 例如,假设卡纳塔克邦的气温为 34 摄氏度; 它表明,在印度卡纳塔克邦,温度为 34 度

Python 中的 @ 符号

发布时间:2023/06/17 浏览次数:138 分类:Python

Python 中 @ 符号最常见的用例是装饰器。 装饰器允许您更改函数或类的行为。@ 符号也可以用作数学运算符,因为它可以在 Python 中乘以矩阵。 本教程将教您使用 Python 的 @ 符号。

Python 堆排序

发布时间:2023/06/17 浏览次数:184 分类:Python

本篇文章将介绍堆排序算法在 Python 中的实现。Python中的堆排序算法 堆排序是一种强大的算法,用于在 Python 中对数组和列表进行排序。 它很受欢迎,因为它非常快,并且不像合并排序和快速排

Python 拓扑排序

发布时间:2023/06/17 浏览次数:102 分类:Python

本篇文章将介绍拓扑排序算法在 Python 中的实现。Python 中的拓扑排序算法 拓扑排序算法对有向无环图 (DAG) 进行排序。

在 Python 中对日期和时间进行排序

发布时间:2023/06/17 浏览次数:82 分类:Python

在本文中,我们讨论了如何在 Python 中使用 sorted() 方法对日期和时间进行排序。 为了理解这个概念,我们举了一些例子以及 Python 中的 datetime 模块。

Python 双样本 T 检验

发布时间:2023/06/17 浏览次数:94 分类:Python

Python 为我们提供的一个功能是我们可以执行双样本 t 检验。 通过本文,我们将讨论什么是双样本 t 检验以及如何使用 Python 执行它。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便