使用Python 的 `tenacity` 库来处理超时重试机制

413 阅读2分钟

Python 的 tenacity 库用于实现重试机制,特别适合处理网络不稳定或其他意外错误导致的函数调用失败。以下是对其主要组件的简明介绍,以及实际应用示例和相应的代码。

组件说明

  • retry: 装饰器,用于标记需要重试的函数。当函数抛出异常时,tenacity 会根据设定的策略自动重试。
  • stop_after_attempt(n) : 设置最大重试次数,参数 n 表示在达到这个次数后停止重试。例如,stop_after_attempt(3) 表示最多重试三次。
  • wait_fixed(seconds) : 设置每次重试之间的固定等待时间,参数 seconds 指定等待的秒数。例如,wait_fixed(2) 表示在每次重试前等待两秒。

使用示例

下面是一个简单的示例,展示如何使用这些组件:

python
from tenacity import retry, stop_after_attempt, wait_fixed

@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
def test_function():
    print("尝试执行...")
    raise Exception("发生错误")

if __name__ == '__main__':
    try:
        test_function()
    except Exception as e:
        print(f"最终失败: {e}")

在这个示例中,test_function 被装饰为在发生异常时最多重试三次,每次重试之间等待两秒。如果三次尝试后仍然失败,程序会捕获并打印最终的错误信息。

实际应用场景

  1. 网络请求

    • 在进行 API 调用时,如果请求失败(例如由于网络问题),可以使用 tenacity 自动重试。
    • 示例代码:
    python
    import requests
    from tenacity import retry, stop_after_attempt, wait_fixed
    
    @retry(stop=stop_after_attempt(5), wait=wait_fixed(3))
    def fetch_data(url):
        response = requests.get(url)
        response.raise_for_status()  # 如果响应状态码不是 200,将抛出异常
        return response.json()
    
    url = "https://api.example.com/data"
    try:
        data = fetch_data(url)
        print("数据获取成功:", data)
    except Exception as e:
        print(f"数据获取失败: {e}")
    
  2. 文件操作

    • 在读取或写入文件时,如果遇到临时性错误(如文件被占用),可以通过重试来增加成功的机会。
    • 示例代码:
    python
    from tenacity import retry, stop_after_attempt, wait_fixed
    
    @retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
    def read_file(file_path):
        with open(file_path, 'r') as file:
            return file.read()
    
    try:
        content = read_file("example.txt")
        print("文件内容:", content)
    except Exception as e:
        print(f"读取文件失败: {e}")
    
  3. 数据库操作

    • 在进行数据库事务时,如果由于连接问题导致失败,可以使用此机制进行重试。
    • 示例代码:
    python
    import sqlite3
    from tenacity import retry, stop_after_attempt, wait_fixed
    
    @retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
    def execute_query(query):
        conn = sqlite3.connect('example.db')
        cursor = conn.cursor()
        cursor.execute(query)
        conn.commit()
        conn.close()
    
    try:
        execute_query("INSERT INTO users (name) VALUES ('Alice')")
        print("插入成功")
    except Exception as e:
        print(f"数据库操作失败: {e}")
    

通过使用 tenacity 库,可以有效提高程序的健壮性,减少因临时性错误导致的失败。这些实际应用场景展示了如何在日常编程中利用该库来处理不稳定因素,从而提升用户体验和系统稳定性。