tenacity==9.1.2 这个 Python 库的核心功能,以及具体的使用方法,我会从基础概念到实际案例一步步讲清楚。
一、tenacity 是什么?
tenacity 是一个功能强大且易用的 Python 重试库,专门用来处理那些可能因为网络波动、资源暂不可用、服务超时等临时性故障 而失败的代码逻辑。它比 Python 标准库的重试方案更灵活,支持自定义重试条件、重试间隔、停止策略等,9.1.2 是该库的一个稳定版本。
简单来说:当你的代码调用接口偶尔失败、连接数据库偶尔超时,不想直接报错,而是希望"再试几次"时,tenacity 就能帮你优雅地实现这个需求。
二、tenacity==9.1.2 的安装
首先需要安装指定版本,确保环境中库版本一致:
bash
pip install tenacity==9.1.2
三、核心使用方法
1. 基础用法(装饰器方式)
这是最常用的方式,通过装饰器给需要重试的函数添加重试逻辑。
python
from tenacity import retry, stop_after_attempt, wait_fixed
# 定义重试规则:最多重试3次,每次间隔2秒
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2))
def call_unstable_api():
"""模拟调用一个不稳定的API,大概率失败"""
import random
if random.random() < 0.8: # 80%概率触发失败
raise ConnectionError("API 连接失败")
return "API 调用成功"
# 调用函数
try:
result = call_unstable_api()
print(result)
except Exception as e:
print(f"最终调用失败:{e}")
关键参数解释:
@retry():核心装饰器,开启重试功能;stop=stop_after_attempt(3):停止条件------最多重试3次(含首次调用);wait=wait_fixed(2):等待策略------每次重试前等待2秒。
2. 高级用法:自定义重试条件+指数退避等待
实际场景中,我们通常只希望对特定异常重试,且重试间隔逐渐变长(指数退避),避免频繁请求压垮服务:
python
from tenacity import (
retry,
stop_after_attempt,
wait_exponential, # 指数退避等待
retry_if_exception_type, # 按异常类型重试
retry_if_result # 按返回结果重试
)
# 规则:仅对ConnectionError重试,最多5次,等待时间2^n秒(n从1开始),最大等待10秒
@retry(
stop=stop_after_attempt(5),
wait=wait_exponential(multiplier=2, min=2, max=10),
retry=retry_if_exception_type(ConnectionError)
)
def call_db():
"""模拟连接数据库"""
import random
if random.random() < 0.7:
raise ConnectionError("数据库连接超时")
return "数据库连接成功"
# 调用
try:
print(call_db())
except ConnectionError as e:
print(f"多次重试后仍失败:{e}")
关键参数补充:
wait_exponential(multiplier=2, min=2, max=10):等待时间按2^重试次数增长,最小2秒,最大10秒(避免等待过久);retry=retry_if_exception_type(ConnectionError):仅当抛出ConnectionError时才重试,其他异常直接报错。
3. 按返回结果重试
有时函数不抛异常,但返回非预期结果(如 None、False),也需要重试:
python
from tenacity import retry, stop_after_attempt, retry_if_result
def check_service_status():
"""模拟检查服务状态,返回True/False"""
import random
return random.random() > 0.8 # 20%概率返回True
# 规则:返回False时重试,最多重试4次
@retry(
stop=stop_after_attempt(4),
retry=retry_if_result(lambda x: x is False)
)
def get_service_status():
status = check_service_status()
print(f"检查结果:{status}")
return status
# 调用
try:
status = get_service_status()
print(f"最终服务状态:{status}")
except Exception as e:
print(f"重试耗尽:{e}")
4. 手动控制重试(非装饰器)
如果不想用装饰器,可手动创建重试器对象:
python
from tenacity import Retrying, stop_after_attempt, wait_fixed
def risky_operation():
import random
if random.random() < 0.8:
raise ValueError("操作失败")
return "操作成功"
# 创建重试器
retryer = Retrying(
stop=stop_after_attempt(3),
wait=wait_fixed(1)
)
# 手动执行重试逻辑
try:
result = retryer(risky_operation)
print(result)
except Exception as e:
print(f"重试失败:{e}")
四、常用核心组件总结
| 组件类型 | 常用方法 | 作用 |
|---|---|---|
| 停止策略 | stop_after_attempt(n) |
最多重试n次 |
stop_after_delay(seconds) |
重试总时长不超过seconds秒 | |
| 等待策略 | wait_fixed(seconds) |
固定间隔等待 |
wait_exponential(multiplier) |
指数退避等待 | |
wait_random(min, max) |
随机间隔等待(避免并发重试撞库) | |
| 重试条件 | retry_if_exception_type(exc) |
特定异常时重试 |
retry_if_result(func) |
特定返回结果时重试 | |
retry_any() |
满足任意一个重试条件就重试 |
总结
tenacity==9.1.2是 Python 重试库,核心解决"临时性故障的代码重试"问题,比手动写循环重试更优雅、灵活;- 核心使用方式是通过
@retry()装饰器,搭配停止策略 (stop)、等待策略 (wait)、重试条件(retry)三大核心参数; - 常见场景:接口调用重试、数据库连接重试、按返回结果重试,可根据需求组合不同策略(如指数退避+特定异常重试)。
使用时需注意:仅对临时性故障重试(如网络超时),不要对永久性错误(如参数错误、权限不足)重试,否则会浪费资源。