首页 > 编程语言 >python 重试装饰器@retryonexception 用法及案例

python 重试装饰器@retryonexception 用法及案例

时间:2024-12-20 14:52:37浏览次数:5  
标签:retries attempt python retryonexception 重试 api data 装饰

在Python中,重试装饰器(@retryonexception)是一种用于在函数或方法执行过程中遇到异常时自动重试的装饰器。这种装饰器对于处理可能由于临时问题(如网络延迟、资源争用等)而失败的操作非常有用。下面是一个简单的重试装饰器的实现及其用法案例:

重试装饰器实现

import time
import functools

def retryonexception(retries=3, delay=2, backoff=2):
    """
    重试装饰器,在遇到异常时重试指定的次数。

    参数:
    retries (int): 最大重试次数。
    delay (int/float): 初始等待时间(秒)。
    backoff (int/float): 等待时间增长因子(每次重试时等待时间乘以这个因子)。
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            attempt = 0
            while attempt < retries:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    attempt += 1
                    wait_time = delay * (backoff ** (attempt - 1))
                    print(f"Attempt {attempt} failed: {e}. Retrying after {wait_time:.2f} seconds...")
                    time.sleep(wait_time)
                    if attempt == retries:
                        print(f"After {attempt} attempts, function '{func.__name__}' failed.")
                        raise  # 重新抛出异常,以便调用者可以处理它
        return wrapper
    return decorator

用法案例

@retryonexception(retries=5, delay=1, backoff=1.5)
def fetch_data_from_api(url):
    # 模拟从API获取数据,这里可能会抛出异常
    import requests
    response = requests.get(url)
    response.raise_for_status()  # 如果响应状态码不是200,会抛出HTTPError异常
    return response.json()

# 调用函数,这里我们假设URL是有效的,但为了演示,我们可以手动触发异常
try:
    data = fetch_data_from_api("http://example.com/api/data")
    print(data)
except Exception as e:
    print(f"Failed to fetch data: {e}")

输出结果(假设API调用失败并触发重试)

Attempt 1 failed: HTTPError 404 Client Error: Not Found for url: http://example.com/api/data. Retrying after 1.00 seconds...
Attempt 2 failed: HTTPError 404 Client Error: Not Found for url: http://example.com/api/data. Retrying after 1.50 seconds...
Attempt 3 failed: HTTPError 404 Client Error: Not Found for url: http://example.com/api/data. Retrying after 2.25 seconds...
Attempt 4 failed: HTTPError 404 Client Error: Not Found for url: http://example.com/api/data. Retrying after 3.38 seconds...
After 5 attempts, function 'fetch_data_from_api' failed.
Failed to fetch data: HTTPError 404 Client Error: Not Found for url: http://example.com/api/data

解释

  1. 装饰器定义retryonexception 是一个装饰器工厂函数,它接受三个参数(retriesdelay 和 backoff),并返回一个装饰器函数 decorator。这个装饰器函数再接受一个函数 func 并返回一个新的函数 wrapper

  2. 重试逻辑:在 wrapper 函数内部,使用 while 循环来尝试执行被装饰的函数 func。如果函数执行成功(没有抛出异常),则返回结果。如果函数抛出异常,则增加尝试次数 attempt,计算等待时间 wait_time(使用指数退避策略),打印错误信息,然后等待指定的时间后再次尝试。

  3. 异常处理:如果达到最大重试次数 retries 后仍然失败,则重新抛出异常,以便调用者可以捕获并处理它。

  4. 装饰器应用:使用 @retryonexception(retries=5, delay=1, backoff=1.5) 来装饰 fetch_data_from_api 函数,指定最大重试次数为5次,初始等待时间为1秒,等待时间增长因子为1.5。

注意事项

  • 重试装饰器对于可能因临时问题而失败的操作非常有用,但不应滥用。对于持续失败的操作,应该考虑使用其他错误处理策略(如回退、告警、记录错误日志等)。
  • 在实际应用中,你可能希望将重试策略(如重试次数、等待时间等)放在一个单独的配置文件中,而不是直接在代码中硬编码。
  • 当使用重试装饰器时,请确保被装饰的函数是幂等的(即多次调用不会改变系统的状态或产生不同的结果)。

标签:retries,attempt,python,retryonexception,重试,api,data,装饰
From: https://www.cnblogs.com/wyj497022944/p/18619293

相关文章

  • python类中 __开头的函数【魔法方法】
    在Python中,魔法方法(MagicMethods)或双下划线方法(DunderMethods)是一类特殊的方法,它们以双下划线(__)开头和结尾。这些方法为对象提供了丰富的功能,允许你定义对象的内置操作行为,如初始化、比较、表示、数学运算等。以下是一些常见的魔法方法及其用途,并附有相应的示例代码。1.初始......
  • python学习——与时间日期相关的方法
    文章目录类方法例子不用考虑闰年了!Python中处理日期和时间的功能主要依赖于datetime模块。类datetime.date:表示日期(年、月、日)的类。datetime.time:表示时间(小时、分钟、秒、微秒)的类。datetime.datetime:表示日期和时间的组合。datetime.timedelta:表......
  • python毕设 基于web的养宠系统的实现程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于宠物管理系统的研究,现有研究主要以宠物领养、销售等传统功能为主。专门针对基于web的综合性养宠系统,涵盖宠物帮遛、遛宠信息等功......
  • 修改python jsonpickle源码, 实现不序列化对象私有成员(3)
    发现之前修改源码后,虽然过滤掉对象的私有成员,但是反序列化的时候,发现生成的对象只有只有公有成员,不包括私有成员.这不是我想要的,因为没有私有成员,对象就不完整了,并且有时候还需要一些私有成员的默认值.所以,还需要再优化一下.修改unpickler.py文件的def_restor......
  • Python旅游信息管理系统v7c4w(Pycharm Flask Django Vue mysql)
    文章目录项目介绍和开发技术介绍具体实现截图开发技术开发与测试:设计思路系统测试可行性分析核心代码部分展示文章目录/写作提纲参考源码/演示视频获取方式项目介绍和开发技术介绍旅游信息管理系统的现状来进行开发的,具体根据现实的需求来实现旅游信息管理系统网络......
  • Python古玩玉器藏品交易系统(Pycharm Flask Django Vue mysql)
    文章目录项目介绍和开发技术介绍具体实现截图开发技术开发与测试:设计思路系统测试可行性分析核心代码部分展示文章目录/写作提纲参考源码/演示视频获取方式项目介绍和开发技术介绍实现了一个古玩玉器交易系统。古玩玉器交易系统的主要用户分为用户、管理员。管理员......
  • python 多版本安装
    当不同的项目需要不同的python版本时,需要安装多个版本的python1.官网下载所有需要的版本:以windows为例:https://www.python.org/downloads/windows/2.安装不同的版本,注意安装路径,默认路径为:C:\Users\Administrator\AppData\Local\Programs\Python......
  • python及pip及pycharm安装
    参考:https://blog.csdn.net/wslejbb/article/details/1379211231、下载pythonhttps://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz2、安装pythonmkdir/usr/local/python3tar-xfPython-3.6.1.tgzcdPython-3.6.1/./configure--prefix=/usr/local/python3make&......
  • 使用Python实现量子通信模拟:探索安全通信的未来
    量子通信作为量子信息科学的一个重要分支,利用量子力学的基本原理实现安全通信,正在引领一场信息安全领域的革命。通过量子通信,信息可以在两个点之间通过量子比特(qubits)进行传输,具有高度的安全性。本文将详细介绍如何使用Python实现量子通信模拟,涵盖量子态的表示、量子纠缠的......
  • python优雅而神奇的parse库
    前言在Python中,format方法和f-strings是两种常用的字符串插值方法。name="Haige"age="18"print(f"{name}is{age}yearsold.")#Haigeis18yearsold.而如果是要从字符串中提取期望的值呢?相信很多人的第一或第二想法是使用正则表达式。熟悉正则表达式的人都明白......