【摸鱼笔记】熟悉Tenacity,让运行更稳固

背景

在程序运行过程中,经常遇到需要处理报错的情况,大部分报错情况重试就能解决;

作为流行的编程语言,python提供了用于简化处理捕捉报错并重试的库,Tenacity 便是其中之一。

简介

Tenacity 是一个 Apache 2.0 许可的通用重试库,用 Python 编写,用于简化向几乎任何事物添加重试行为的任务。

它具有如下特性:

  • 通用装饰器 API
  • 指定停止条件(即尝试次数限制)
  • 指定等待条件(即尝试之间的阻塞)
  • 自定义重试异常
  • 自定义对预期返回结果的重试
  • 重试协程
  • 使用上下文管理器重试代码块

安装

pip install tenacity

基本用法

Tenacity的基本用法是装饰器,该装饰器可以应用于函数或方法以实现重试操作;

示例

import tenacity@tenacity.retry(stop=tenacity.stop_after_attempt(3))
def func_execute():print("the long way rounds...")raise Exception("Exception!")try:func_execute()
except Exception as e:print(f"Exception: {e}")

运行结果

the long way rounds...
the long way rounds...
the long way rounds...
Exception: RetryError[<Future at 0x1874323ddc0 state=finished raised Exception>]

func_execute函数中,手动抛出异常;

@tenacity.retry装饰器来修饰函数func_execute

如果@tenacity.retry中没有配置tenacity.stop_after_attempt将会无限循环;

示例中配置了重试策略,即在前三次尝试后停止重试tenacity.stop_after_attempt(3)

由于配置了重试,Tenacity将在抛出异常时重试该函数,最多重试3次,在运行结果中可以看到函数中的 print 执行了三次。

配置选项

除了重试次数,Tenacity还提供了许多其他配置选项;

以下是一些常用的配置选项

retry

定义在哪些异常情况下执行重试,可以根据异常类型等自定义的条件;

tenacity.retry_if_exception_type(exception_types)

捕捉到 与参数 exception_types 匹配的异常类型时重试

参数 exception_types :装饰对象抛出匹配异常后才会重试,其他的会忽略

示例

import tenacity@tenacity.retry(retry=tenacity.retry_if_exception_type(IOError),stop=tenacity.stop_after_attempt(5))
def func_execute(param: str):print(param)raise IOError("IOError")try:func_execute("the long way rounds.")
except Exception as e:print(f"Exception: {e}")

运行结果

the long way rounds.
the long way rounds.
the long way rounds.
the long way rounds.
the long way rounds.
Exception: RetryError[<Future at 0x20d5d03f0e0 state=finished raised OSError>]

tenacity.retry_if_result(predicate)

装饰器装饰对象返回 参数 predicate 匹配结果值 为True时重试

参数 predicate :用于判断返回值是否匹配的函数,其他的会忽略

示例

import tenacitydef retry_decide(result: str) -> bool:# 此处 func_execute 返回值为 None,# 返回给retry_if_result的值将是True# 不管是否报错都会重试return result is None@tenacity.retry(retry=tenacity.retry_if_result(retry_decide),stop=tenacity.stop_after_attempt(5))
def func_execute():print("执行 func_execute()")# 此处返回 Nonereturn Nonetry:result = func_execute()
except Exception as e:print(f"Exception: {e}")

运行结果

the long way rounds.
the long way rounds.
the long way rounds.
the long way rounds.
the long way rounds.
Exception: RetryError[<Future at 0x20d5d03f0e0 state=finished raised OSError>]

stop

定义停止的条件,可以根据重试次数、重试时间等条件;

tenacity.stop_after_attempt(max_attempt_number:int)

参数 max_attempt_number :最大尝试次数,即超过尝试次数后抛出异常

示例

import tenacity@tenacity.retry(stop=tenacity.stop_after_attempt(5))
def func_execute():print("执行 func_execute()")raise Exception("抛出")try:result = func_execute()
except Exception as e:print(f"Exception: {e}")
执行 func_execute()
执行 func_execute()
执行 func_execute()
执行 func_execute()
执行 func_execute()
Exception: RetryError[<Future at 0x18ccf4fea80 state=finished raised Exception>]

tenacity.stop_after_delay(max_delay:int)

参数 max_delay :最大尝试时长(单位为秒),即超过尝试时长后抛出异常

示例

import datetime as dtimport tenacity@tenacity.retry(stop=tenacity.stop_after_delay(5),wait=tenacity.wait_fixed(2))
def func_execute():print("执行 func_execute()", dt.datetime.now().strftime("%H:%M:%S"))raise Exception("抛出")try:result = func_execute()
except Exception as e:print(f"Exception: {e}")

运行结果

执行 func_execute() 16:40:02
执行 func_execute() 16:40:04
执行 func_execute() 16:40:06
执行 func_execute() 16:40:08
Exception: RetryError[<Future at 0x1d6622ae810 state=finished raised Exception>]

wait

定义每次重试之间的等待时间,一般是固定的等待时间,也可以设置每次递增;

tenacity.wait_fixed(wait)

参数 wait :每次重试的间隔时间

示例

import datetime as dtimport tenacity@tenacity.retry(stop=tenacity.stop_after_attempt(2),wait=tenacity.wait_fixed(2))
def func_execute():print("执行 func_execute()", dt.datetime.now().strftime("%H:%M:%S"))raise Exception("抛出")try:result = func_execute()
except Exception as e:print(f"Exception: {e}")

运行结果

执行 func_execute() 16:41:19
执行 func_execute() 16:41:21
Exception: RetryError[<Future at 0x1e84b9ff4a0 state=finished raised Exception>]

tenacity.wait_random(min,max)

参数 min :随机间隔时间范围下限
参数 max :随机间隔时间范围上限

示例

import datetime as dtimport tenacity@tenacity.retry(stop=tenacity.stop_after_delay(10),wait=tenacity.wait_random(2, 5))
def func_execute():print("执行 func_execute()", dt.datetime.now().strftime("%H:%M:%S"))raise Exception("抛出")try:result = func_execute()
except Exception as e:print(f"Exception: {e}")

运行结果

执行 func_execute() 16:42:14
执行 func_execute() 16:42:16
执行 func_execute() 16:42:19
执行 func_execute() 16:42:22
执行 func_execute() 16:42:25
Exception: RetryError[<Future at 0x1bd3737ed50 state=finished raised Exception>]

before_sleep

在每次重试之前执行的操作,可以用于执行清理或日志记录等任务。

before_sleep_log(logger, log_level)

参数 logger :日志记录器对象

参数 log_level :日志记录等级 debug, info 等

示例

import datetime as dt
import logging
import sysimport tenacitylogging.basicConfig(stream=sys.stderr, level=logging.DEBUG)logger = logging.getLogger(__name__)@tenacity.retry(retry=tenacity.retry_if_exception_type(IOError),stop=tenacity.stop_after_attempt(3),wait=tenacity.wait_fixed(2),before_sleep=tenacity.before_sleep_log(logger, logging.DEBUG))
def func_execute(param: str):print(param, dt.datetime.now().strftime("%H:%M:%S"))raise IOError("IOError")try:func_execute("the long way rounds.")
except Exception as e:print(f"Exception: {e}")

运行结果

DEBUG:__main__:Retrying __main__.func_execute in 2.0 seconds as it raised OSError: IOError.
the long way rounds. 16:43:24
the long way rounds. 16:43:26
DEBUG:__main__:Retrying __main__.func_execute in 2.0 seconds as it raised OSError: IOError.
the long way rounds. 16:43:28
Exception: RetryError[<Future at 0x2357a3be090 state=finished raised OSError>]

reraise

是否重新引发异常,如果设置为True,则在达到最大重试次数后会引发原始异常。

示例

import tenacity@tenacity.retry(retry=tenacity.retry_if_exception_type(IOError),stop=tenacity.stop_after_attempt(3),reraise=True)
def func_execute(param: str):print(param)raise IOError("IOError")try:func_execute("the long way rounds.")
except Exception as e:print(f"Exception: {e}")

运行结果

the long way rounds.
the long way rounds.
the long way rounds.
Exception: IOError

组合重试条件

自定义重试策略,以满足指定条件下重试或停止重试。

示例

import tenacity# 在同一个 配置项中组合配置条件
@tenacity.retry(stop=tenacity.stop_after_delay(10) | tenacity.stop_after_attempt(5),retry=tenacity.retry_if_exception_type(IOError))
def func_execute():print("Operation with Custom Stop...")raise IOError("Failed!")try:func_execute()
except Exception as e:print(f"Exception: {e}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/386449.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端web开发HTML+CSS3+移动web(0基础,超详细)——第1天

一、开发坏境的准备 1&#xff0c;在微软商店下载并安装VS Code 以及谷歌浏览器或者其他浏览器&#xff08;我这里使用的是Microsoft Edge&#xff09; 2&#xff0c;打开vs code &#xff0c;在电脑桌面新建一个文件夹命名为code&#xff0c;将文件夹拖拽到vs code 中的右边…

空气处理机组系统中的设计和选型参考

1、静压的选择&#xff1a; 1.机组所承受的正压值和负压值既不是指机组的机外静压&#xff0c;也不是指风机的压头&#xff0c;而是指机组内部与机组外部大气压的差值&#xff0c;具体的计算方法如下&#xff1a; 如图所示&#xff0c;机组的新、回、送风管阻力分别为A、B、C帕…

【轨物方案】开关柜在线监测物联网解决方案

随着物联网技术的发展&#xff0c;电力设备状态监测技术也得到了迅速发展。传统的电力成套开关柜设备状态监测方法主要采用人工巡检和定期维护的方式&#xff0c;这种方法不仅效率低下&#xff0c;而且难以保证设备的实时性和安全性。因此&#xff0c;基于物联网技术的成套开关…

Qt自定义MessageToast

效果&#xff1a; 文字长度自适应&#xff0c;自动居中到parent&#xff0c;会透明渐变消失。 CustomToast::MessageToast(QS("最多添加50张图片"),this);1. CustomToast.h #pragma once#include <QFrame>class CustomToast : public QFrame {Q_OBJECT pub…

图——“多对多”的逻辑结构

目录 1.什么是图&#xff1f; 图包含&#xff1a; 2.图的基本术语 无向图&#xff1a; 有向图&#xff1a; 权重&#xff1a;边上的数字 度&#xff1a; 邻接点&#xff1a; 完全图&#xff1a; 3.图的抽象数据类型定义 4.怎么在程序中表示一个图&#xff1f; 邻接矩…

Java的日期类

1.第一代日期类 ① Date类&#xff1a;精确到毫秒&#xff0c;代表特定的瞬间 public static void main(String[] args) { // 获取当前系统时间 // 这里的Date类是在java.util包 // 默认输出的格式是国外的格式Date date new Date();System.out.println…

C#体检系统源码,医院健康体检系统PEIS,C#+VS2016+SQLSERVER

体检中心/医院体检科PEIS系统源码&#xff0c;C#健康体检信息系统源码&#xff0c;PEIS源码 开发环境&#xff1a;C/S架构C#VS2016SQLSERVER 2008 检前&#xff1a; 多种预约方式网站预约、电话预约、微信平台预约及检前沟通&#xff0c;提前制作套餐&#xff0c;客人到达体检…

【原创】java+ssm+mysql医生信息管理系统设计与实现

个人主页&#xff1a;程序员杨工 个人简介&#xff1a;从事软件开发多年&#xff0c;前后端均有涉猎&#xff0c;具有丰富的开发经验 博客内容&#xff1a;全栈开发&#xff0c;分享Java、Python、Php、小程序、前后端、数据库经验和实战 开发背景&#xff1a; 随着信息技术的…

【七】Hadoop3.3.4基于ubuntu24的分布式集群安装

文章目录 1. 下载和准备工作1.1 安装包下载1.2 前提条件 2. 安装过程STEP 1: 解压并配置Hadoop选择环境变量添加位置的原则检查环境变量是否生效 STEP 2: 配置Hadoop2.1. 修改core-site.xml2.2. 修改hdfs-site.xml2.3. 修改mapred-site.xml2.4. 修改yarn-site.xml2.5. 修改hado…

【Linux从青铜到王者】tcp协议2

滑动窗口 滑动窗口是什么 上篇提到如果两端发送数据如果是一发一收那就是串行&#xff0c;效率很低&#xff0c;所以可以一次发送多个报文&#xff0c;一次也可以接受多个报文&#xff0c;可以大大的提高性能(其实是将多个段的等待时间重叠在一起了&#xff09; 那么是怎么发…

解锁人工智能学习中的数学密钥

一、启航&#xff1a;奠定数学基础 1. 线性代数&#xff1a;AI的入门语言 学习目标&#xff1a;掌握向量、矩阵的基本概念及运算&#xff0c;理解线性空间、线性变换及特征值、特征向量的意义。学习建议&#xff1a;从基础教材入手&#xff0c;如《线性代数及其应用》&#x…

【黄啊码】零代码动手创建ModelScope Agent

还没开始学习&#xff0c;先来回复一下&#xff0c;什么是Agent Agent包含的模块 好了&#xff0c;开始发放干货&#xff1a; 1、创建通义千问API (新注册用户有一定的限时免费额度) 2、登录阿里云账号&#xff0c;打开 DashScope管理控制台&#xff0c;开通 DashScope灵积模…

WinUI vs WPF vs WinForms: 三大Windows UI框架对比

1.前言 在Windows平台上开发桌面应用程序时&#xff0c;WinUI、WPF和WinForms是三种主要的用户界面框架。每种框架都有其独特的特点和适用场景。本文将通过示例代码&#xff0c;详细介绍这些框架的优缺点及其适用场景&#xff0c;帮助dotnet桌面开发者更好地选择适合自己项目的…

使用EasyAR打包安卓操作注意

EasyAR for Scene 4.6.3 丨Unity2020.3.15f2 打包Unity注意事项 一、默认渲染管线 官方参考链接&#xff1a;ARFoundation 简单注意 1.打包设置为Android平台 2.PackageName和EasyAR中保持一致 3.Scripting Backend设置为IL2CPP&#xff0c;以及设置为ARM64 4.取消Auto …

数据结构·红黑树

1. 红黑树的概念 红黑树&#xff0c;是一种搜索二叉树&#xff0c;但在每个节点上增加一个存储位表示节点的颜色&#xff0c;可以是Red或Black。通过对任意一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c;因…

秋招突击——7/29——复习{有塔游戏——关联传递性}——新作{随机链表的复制、合并K个升序链表,二叉树——二叉树的中序遍历、二叉树的最大深度、反转二叉树}

文章目录 引言复习有塔游戏——关联传递性实现复习实现参考实现 新作随机链表的复制个人实现参考实现 排序链表个人实现参考实现 二叉树章节二叉树的中序遍历个人实现 二叉树的最大深度个人实现参考实现 反转二叉树个人实现参考实现 总结 引言 旅游完回来了&#xff0c;今天继…

Matlab编程资源库(14)常微分方程初值问题的数值解法

一、 龙格&#xff0d;库塔法简介 龙格-库塔法&#xff08;Runge-Kutta method&#xff09;是一种常用的数值解微分方程的方法&#xff0c;由德国数学家卡尔龙格&#xff08;Carl Runge&#xff09;和马丁威尔海尔姆库塔&#xff08;Martin Wilhelm Kutta&#xff09;在20世纪…

IDEA 本地有jar包依赖文件,但是所有引用的jar包全部爆红

前端时间 看源码&#xff0c;下载源码额按钮不见了&#xff0c;折腾了很久&#xff0c;遂打算重新安装idea&#xff0c;但是重新安装后&#xff0c;发现代码全都爆红&#xff0c;按照晚上说的删除idea 文件夹&#xff0c;idea缓存删除&#xff0c;都不好使&#xff0c;但是看到…

【JavaScript】`Map` 数据结构

文章目录 一、Map 的基本概念二、常见操作三、与对象的对比四、实际应用场景 在现代 JavaScript 中&#xff0c;Map 是一种非常重要且强大的数据结构。与传统的对象&#xff08;Object&#xff09;不同&#xff0c;Map 允许您使用各种类型的值作为键&#xff0c;不限于字符串或…

机器学习算法——常规算法,在同的业务场景也需要使用不同的算法(一)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…