首页 > 编程语言 >Python装饰器实战:实现优雅的重试机制

Python装饰器实战:实现优雅的重试机制

时间:2024-03-29 14:11:36浏览次数:29  
标签:delay retry retries Python 优雅 重试 time 机制

重试机制在编程中是比较常见的场景,主要被用于处理那些可能由于临时性故障或网络波动等原因而失败的操作。

本文介绍如何通过Python装饰器来实现重试机制
从而能够在尽量少修改现有代码的基础上,给其中某些函数加上重试机制

1. 概要

关于Python的装饰器,只是一个语法糖,原理也比较简单,这里不在赘述。

关于为什么要用重试机制
首先,它能显著提高了系统的稳定性和可靠性。
因为,在分布式系统、网络通信或任何涉及外部资源调用的场景中,失败和异常是难以避免的。
通过引入重试机制,系统能够在遇到这些临时性故障时自动恢复,减少因单次失败导致的整体服务中断。

其次,重试机制有助于提升用户体验。
对于用户来说,如果系统因为一次网络抖动或短暂的服务器不可用就抛出错误,那么用户可能会感到不满。
通过重试机制,系统可以在用户几乎无感知的情况下恢复服务,从而提升用户体验。

此外,重试机制还可以帮助系统更好地应对突发的高负载或资源紧张的情况。
当系统面临大量请求或资源争用时,某些操作可能会因为资源不足而失败。
通过合理设置重试间隔和重试次数,系统可以平滑地处理这些突发情况,避免因为短暂的资源不足而导致服务崩溃。

2. 实现重试机制

下面是我目前在用的一个重试装饰器:

from functools import wraps
from time import sleep


def retry(retries: int = 3, delay: float = 1):
    """
    函数执行失败时,重试

    :param retries: 最大重试的次数
    :param delay: 每次重试的间隔时间,单位 秒
    :return:
    """

    # 校验重试的参数,参数值不正确时使用默认参数
    if retries < 1 or delay <= 0:
        retries = 3
        delay = 1

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 第一次正常执行不算重试次数,所以retries+1
            for i in range(retries + 1):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    # 检查重试次数
                    if i == retries:
                        print(f"Error: {repr(e)}")
                        print(f'"{func.__name__}()" 执行失败,已重试{retries}次')
                        break
                    else:
                        print(
                            f"Error: {repr(e)},{delay}秒后第[{i+1}/{retries}]次重试..."
                        )
                        sleep(delay)

        return wrapper

    return decorator

这个装饰器有两个参数,一个是重试次数(retries),一个是每次重试的间隔(delay)。
代码比较简单,通过捕获函数func的异常来重试,重试次数达到最大重试次数后退出。

3. 使用重试机制示例

使用上面装饰器的示例:

from decorators import retry
import time


@retry(retries=2, delay=2)
def pay():
    now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print(f"[{now}]: 开始调用支付接口")
    raise Exception("调用支付接口超时...")


@retry(retries=5, delay=1)
def third():
    now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    print(f"[{now}]: 开始调用第三方接口")
    raise Exception("调用第三方接口超时...")


if __name__ == "__main__":
    pay()  # 重试2次,每次间隔2秒
    third()  # 重试5次,每次间隔1秒

模拟一个支付接口,一个调用第三方的接口,分别看看重试的效果。
image.png
简简单单给函数加一个@retry,就有了重试功能。

4. 总结

总之,在设计和开发系统时,合理地引入和应用重试机制是非常必要的,尤其是需要大量调用第三方服务的时候。
通过装饰器的方式来实现重试机制,能够尽量少的侵入代码的业务逻辑,是一种优雅灵活的方式。

标签:delay,retry,retries,Python,优雅,重试,time,机制
From: https://www.cnblogs.com/wang_yb/p/18103745

相关文章

  • python获取视频时长并移动到对应时长的文件夹下
    importosimportshutilfrommoviepy.editorimportVideoFileClip#获取所有文件defgetAllFiles(fire_dir):filepath_list=[]forroot,folder_names,file_namesinos.walk(fire_dir):forfile_nameinfile_names:file_path=root+os......
  • 2023年全国青少年信息素养大赛 第9届Python编程挑战赛北京赛区(小学组)复赛试题解析
    2023年全国青少年信息素养大赛第9届Python编程挑战赛北京赛区(小学组)复赛试题解析T1.求余数题目描述:输入一个正整数,输出这个整数除以5的余数。输入描述:输入一行一个正整数输出描述:输出这个整数除以5的余数样例1:输入:12输出:2#示例代码n=int(input())print(n%5)......
  • 学python如何找工作
    很多小伙伴加我好友问“行哥,我学python要多久才能找到工作呢?”但是经过行哥的仔细分析之后,发现这个问题很有意思首先每个求职者的在没有描述自己的专业,学历,年龄,性格,每日学习时长,个人学习方法的情况下,所以在你没求职之前,行哥⽆法确定你的求职的状态是够就业还是不事业,所以......
  • 零基础转行学Python有发展前景吗?
    前言Python可用的地方非常多。无论是从入门级选手(爬虫、前端、后端、自动化运维)到专业级数据挖掘、科学计算、图像处理、人工智能,Python都可以胜任。或许是因为这种万能属性,周围好更多的小伙伴都开始学习Python。而现在Python的火爆已经来到了程序员的圈子外,进入了国务院......
  • 来不及细说,毕业三天靠Python兼职赚了两千
    考了英语四六级,没办法用英语交流3分钟。考了普通话证书,却没有一个HR关心这个。不喜欢自己的专业,没有好好学。万万没想到,大学四年,学到最有用的东西是驾驶证。这扎心的现实,每一个都让我崩溃!可是,就算是最有用的驾驶证,在想实现财富自由,轻松赚钱上还是无济于事。但是,当我把......
  • 如何优雅的查看方法耗时,不用写一行代码!这个插件支持的太多了
    前言没错,又是CoolRequest插件,这次引来一个重大更新,可以统计任意方法耗时,先上个图。另外,这是此次更新的功能。什么是CoolRequestCoolRequest是一个IDEA中的接口调试插件,除了可以发起基本的HTTP请求之外,还提供了强大的反射调用能力,可以绕过拦截器,这点广受网友的好评,当然伴......
  • python 去除图片中指定颜色框或线
    目录Python去除图片中指定颜色框或线思路和步骤代码实现示例代码主要特点:一些常用功能:与OpenCV的区别:结语Python去除图片中指定颜色框或线在图像处理中,有时候我们需要对图片进行一些特定颜色框或线的处理,例如去除指定颜色的框或线。Python提供了强大的图像处理库Op......
  • python 根据 字符串生成唯一值
    目录Python根据字符串生成唯一值方法一:利用哈希算法生成唯一值方法二:使用UUID生成唯一值方法三:结合加密算法生成唯一值用户注册唯一标识符UUID(UniversallyUniqueIdentifier)特点:UUID版本:Python中使用UUID:应用场景:Python根据字符串生成唯一值在很多应用场景中,我......
  • Python逆向爬虫入门教程: 千千音乐加密参数 sign 逆向解析
    数据来源分析......
  • 7.Python Spark安装
    7.1Scla安装下载:wget https://scala-lang.org/files/archive/scala-2.13.0.tgz解压:tarxvfscala-2.13.0.tgz移动到/usr/local目录:sudomvscala-2.13.0/usr/local/scala设置Scala环境变量:sudogedit~/.bashrc source~/.bashrc启动scala :q退出7.2安装Sparkwg......