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

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

本文介绍如何通过Python装饰器 来实现重试机制 ,

从而能够在尽量少修改现有代码的基础上,给其中某些函数加上重试机制。

1. 概要

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

关于为什么要用重试机制 ,

首先,它能显著提高了系统的稳定性和可靠性。

因为,在分布式系统、网络通信或任何涉及外部资源调用的场景中,失败和异常是难以避免的。

通过引入重试机制,系统能够在遇到这些临时性故障时自动恢复,减少因单次失败导致的整体服务中断。

其次,重试机制 有助于提升用户体验。

对于用户来说,如果系统因为一次网络抖动或短暂的服务器不可用就抛出错误,那么用户可能会感到不满。

通过重试机制,系统可以在用户几乎无感知的情况下恢复服务,从而提升用户体验。

此外,重试机制 还可以帮助系统更好地应对突发的高负载或资源紧张的情况。

当系统面临大量请求或资源争用时,某些操作可能会因为资源不足而失败。

通过合理设置重试间隔和重试次数,系统可以平滑地处理这些突发情况,避免因为短暂的资源不足而导致服务崩溃。

2. 实现重试机制

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

python 复制代码
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. 使用重试机制示例

使用上面装饰器的示例:

python 复制代码
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秒

模拟一个支付接口,一个调用第三方的接口,分别看看重试的效果。

简简单单给函数加一个@retry,就有了重试功能。

4. 总结

总之,在设计和开发系统时,合理地引入和应用重试机制 是非常必要的,尤其是需要大量调用第三方服务的时候。

通过装饰器的方式来实现重试机制,能够尽量少的侵入代码的业务逻辑,是一种优雅灵活的方式。

相关推荐
杨杨杨大侠5 小时前
Jev、Kev、Laya:决策模型怎么选,什么时候需要微调?
人工智能·python·agent
LOVE️YOU5 小时前
Python 在定义函数时,究竟定义的是什么?
python
段一凡-华北理工大学5 小时前
大模型应用开发 100 天:Python + LLM 从入门到精通 day26~Prompt 调试与优化——A/B 测试与效果评估
windows·python·大模型·prompt·智能体·提示词工程·高炉智能化
Minecraft红客5 小时前
以撒的结合
python·游戏·电脑·娱乐
Circ.6 小时前
Python 调试 Litellm 本地大模型接口:模型列表与对话接口实操踩坑记录
开发语言·python
风早爽太6 小时前
用 ‌Render‌ 快速部署网站和常见问题解决
python·fastapi
李航19837 小时前
给自己的图形引擎,配上了AI渲染,做设计真是太方便了
人工智能·python·计算机视觉·ai·ai编程
L@ncor8 小时前
第六章 框架开发实践 · 学习笔记(AutoGen / AgentScope / CAMEL / LangGraph)
python·框架·autogen·langgraph·agentscope
Zhou1411368 小时前
SpringSecurity_02_授权与高级功能
开发语言·python
摇滚侠9 小时前
《On Java 中文版 基础卷》阅读笔记 对象无处不在 03
java·笔记·python