Python中最强大的错误重试库
❝
本文示例代码及文件已上传至我的
Github
仓库https://github.com/CNFeffery/DataScienceStudyNotes❞
1 简介
我们在编写程序尤其是与网络请求相关的程序,如调用web接口、运行网络爬虫等任务时,经常会遇到一些偶然发生的请求失败的状况,这种时候如果我们仅仅简单的捕捉错误然后跳过对应任务,肯定是不严谨的,尤其是在网络爬虫中,会存在损失有价值数据的风险。
这类情况下我们就很有必要为我们的程序逻辑添加一些「错误重试」的策略,费老师我在几年前写过文章介绍过Python
中的retry
库,但它功能较为单一,只能应对基本的需求。
而今天我要给大家介绍的tenacity
库,可能是目前Python
生态中最好用的错误重试库,下面就让我们一睹其主要功能吧~
2 tenacity中的常用功能
作为一个第三方Python
库,我们可以使用pip install tenacity
对其进行安装,安装完成后,下面我们来学习一下tenacity
的主要使用方法和特性:
2.1 tenacity的基础使用
tenacity
的错误重试核心功能由其retry
装饰器来实现,默认不给retry
装饰器传参数时,它会在其所装饰的函数运行过程抛出错误时不停地重试下去,譬如下面这个简单的例子:
import random
from tenacity import retry@retry
def demo_func1():a = random.random()print(a)if a >= 0.1:raise Exceptiondemo_func1()
可以看到,我们的函数体内每次生成0到1之间的随机数,当这个随机数不超过0.1时才会停止抛出错误,否则则会被tenacity
捕捉到每次的错误抛出行为并立即重试。
2.2 设置最大重试次数
有些时候我们对某段函数逻辑错误重试的忍耐是有限度的,譬如当我们调用某个网络接口时,如果连续n次都执行失败,我们可能就会认为这个任务本身就存在缺陷,不是通过重试就能有朝一日正常的。
这种时候我们可以利用tenacity
中的stop_after_attempt
函数,作为retry()
中的stop
参数传入,从而为我们“无尽”的错误重试过程添加一个终点,其中stop_after_attempt()
接受一个整数输入作为「最大重试」的次数:
from tenacity import retry, stop_after_attempt@retry(stop=stop_after_attempt(3))
def demo_func2():print('函数执行')raise Exceptiondemo_func2()
可以看到,我们的函数在限制了最大重试次数后,经过3次重试,在第4次继续执行依然抛出错误后,正式地抛出了函数中对应的Exception
错误结束了重试过程。
2.3 设置重试最大超时时长
我们除了像上一小节中那样设置最大错误重试的次数之外,tenacity
还为我们提供了stop_after_delay()
函数来设置整个重试过程的最大耗时,超出这个时长也会结束重试过程:
import time
from tenacity import retry, stop_after_delay# 设置重试最大超时时长为5秒
@retry(stop=stop_after_delay(5))
def demo_func3():time.sleep(1)print(f'已过去 {time.time() - start_time} 秒')raise Exception# 记录开始时间
start_time = time.time()
demo_func3()
2.4 组合重试停止条件
如果我们的任务同时需要添加最大重试次数以及最大超时时长限制,在tenacity
中仅需要用|
运算符组合不同的限制条件再传入retry()
的stop
参数即可,譬如下面的例子,当我们的函数执行重试超过3秒或次数大于5次时均可以结束重试:
import time
import random
from tenacity import retry, stop_after_delay, stop_after_attempt@retry(stop=(stop_after_delay(3) | stop_after_attempt(5)))
def demo_func4():time.sleep(random.random())print(f'已过去 {time.time() - start_time} 秒')raise Exception# 记录开始时间
start_time = time.time()
demo_func4()
可以看到,在上面的演示中,先达到了“最大重试5次”的限制从而结束了重试过程。
2.5 设置相邻重试之间的时间间隔
有些情况下我们并不希望每一次重试抛出错误后,立即开始下一次的重试,譬如爬虫任务中为了更好地伪装我们的程序,tenacity
中提供了一系列非常实用的函数,配合retry()
的wait
参数,帮助我们妥善处理相邻重试之间的时间间隔,其中较为实用的主要有以下两种方式:
2.5.1 设置固定时间间隔
我们通过使用tenacity
中的wait_fixed()
可以为相邻重试之间设置固定的等待间隔秒数,就像下面的简单示例那样:
import time
from tenacity import retry, wait_fixed, stop_after_attempt# 设置重试等待间隔为1秒
@retry(wait=wait_fixed(1), stop=stop_after_attempt(3))
def demo_func5():print(f'已过去 {time.time() - start_time} 秒')raise Exception# 记录开始时间
start_time = time.time()
demo_func5()
2.5.2 设置随机时间间隔
除了设置固定的时间间隔外,tenacity
还可以通过wait_random()
帮助我们为相邻重试设置均匀分布随机数,只需要设置好均匀分布的范围即可:
import time
from tenacity import retry, wait_random, stop_after_attempt# 设置重试等待间隔为1到3之间的随机数
@retry(wait=wait_random(min=1, max=3), stop=stop_after_attempt(5))
def demo_func6():print(f'已过去 {time.time() - start_time} 秒')raise Exception# 记录开始时间
start_time = time.time()
demo_func6()
可以观察到,每一次重试后的等待时长都是随机的~
2.6 自定义是否触发重试
tenacity
中retry()
的默认策略是当其所装饰的函数执行过程“抛出任何错误”时即进行重试,但有些情况下我们需要的可能是对特定错误类型的捕捉/忽略,亦或是对异常计算结果的捕捉。
tenacity
中同样内置了相关的实用功能:
2.6.1 捕捉或忽略特定的错误类型
使用tenacity
中的retry_if_exception_type()
和retry_if_not_exception_type()
,配合retry()
的retry
参数,我们可以对特定的错误类型进行捕捉或忽略:
from tenacity import retry, retry_if_exception_type, retry_if_not_exception_type@retry(retry=retry_if_exception_type(FileExistsError))
def demo_func7():raise TimeoutError@retry(retry=retry_if_not_exception_type(FileNotFoundError))
def demo_func8():raise FileNotFoundError
2.6.2 自定义函数结果条件判断函数
我们可以编写额外的条件判断函数,配合tenacity
中的retry_if_result()
,实现对函数的返回结果进行自定义条件判断,返回True
时才会触发重试操作:
import random
from tenacity import retry, retry_if_result@retry(retry=retry_if_result(lambda x: x >= 0.1))
def demo_func9():a = random.random()print(a)return a# 记录开始时间
demo_func9()
2.7 对函数的错误重试情况进行统计
被tenacity
的retry()
装饰的函数,我们可以打印其retry.statistics
属性查看其历经的错误重试统计记录结果,譬如这里我们对前面执行过的示例函数demo_func9()
的统计结果进行打印:
demo_func9.retry.statistics
除了上述的功能之外,tenacity
还具有很多特殊的特性,可以结合logging
模块、异步函数、协程等其他Python
功能实现更高级的功能,感兴趣的朋友可以前往https://github.com/jd/tenacity
了解更多。
以上就是本文的全部内容,欢迎在评论区与我进行讨论~
觉得还不错就给我一个小小的鼓励吧!
Python中最强大的错误重试库相关推荐
- Python 中最强大的错误重试库
作者 | 费弗里 来源丨Python大数据分析 1 简介 我们在编写程序尤其是与网络请求相关的程序,如调用web接口.运行网络爬虫等任务时,经常会遇到一些偶然发生的请求失败的状况,这种时候如果我们仅仅 ...
- 小结两种在Python中导入C语言扩展库的方法
小结两种在Python中导入C语言扩展库的方法 分类: Pythoner2009-08-18 20:44 2563人阅读 评论(1) 收藏 举报 python扩展c语言importstring 一种是 ...
- python一直报缩进错误_如何避免Python中的缩进错误
Python是当今编程界领先和新兴的编程平台之一.凭借其丰富的功能和巨大的灵活性,人们可以在这个平台上实现很多,只要他们知道如何操作它.在Python中的这个缩进错误中,我们将介 Python是当今编 ...
- 成功解决Python中导出图片出现错误SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position
成功解决Python中导出图片出现错误SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position ...
- linux 下的动态库制作 以及在python 中如何调用 c 函数库
linux 下的动态库制作 以及在python 中如何调用 c 函数库 动态库: 动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序 ...
- 【Python中的权限错误:无法访问文件】-- 解决方案
[Python中的权限错误:无法访问文件]-- 解决方案 在Python编程过程中,我们常常会遇到文件读写.创建.删除等操作.有时候当我们试图进行这些操作时,会出现"PermissionEr ...
- 捋一捋Python中的数学运算math库(上篇)
正式的Python专栏第18篇,同学站住,别错过这个从0开始的文章! 很多学习编程的都多多少少学习了一些数学知识. 学委之前也简单吐槽了 Python中奇葩的round函数! 这篇我们讲讲那些常用的数 ...
- 关于python语言下列说法错误的是_在Python中下列说法错误的是()
在Python中下列说法错误的是() 答:Python语言只能用4个空格的缩进来实现程序的强制可读性 比赛中,运动员击出的球压在端线上,则判该运动员失分 答:× 虚证的症状表现是( ) 答:神疲乏力 ...
- Python 中 xpath 语法 与 lxml 库解析 HTML/XML 和 CSS Selector
The lxml.etree Tutorial :https://lxml.de/tutorial.html python3 解析 xml:https://www.cnblogs.com/deadwo ...
- python中的eof错误_python – 解析器YACC中的EOF错误
我试图使用PLY库中为Python提供的yacc解析器来解析字符串. 解析器本身很长,但我遇到的问题是它总是给我同样的错误,无论我放什么样的字符串. 错误是这样的: yacc:输入中的解析错误. EO ...
最新文章
- fileinput_open_读写文件_python
- C#中equal与==的区别
- DJANGO用户名认证一例
- 实验四+149+肖雷
- 程序员成长之路 java面试指导(作者说的极好要看) 静下心看
- php5.3+for+linux,Centos 安装 nginx + php5.3
- 关于Spring注解开发教程,打包全送你
- adb shell操作文件
- 面试突击41:notify是随机唤醒吗?
- Android内存优化12 内存泄漏常见情况3 注册泄漏
- Mac 更新系统后无法使用git
- Scrum板与Kanban如何抉择?敏捷工具:otmic板与按照mtygdmam
- linux开机启动任务和定时执行任务
- 【新手】关于路径格式的问题(错误提示incomplete universal character name)
- Lisp语言:列表(List)
- 轻松可视化实现设备监控大屏效果
- win10台式机一根网线连接笔记本wifi网络
- logitech g27 matlab,HiPole 模拟赛车入门神器Logitech G27测评
- 把jpg转换成pdf教程
- 基于SpringBoot的高校在线答疑管理系统
热门文章
- HarmonyOS resources目录中“限定词目录”命名要求
- (java中的super)不会飞还能叫Superman吗
- jsp异常 The JSP specification requires that an attribute name is preceded by whitespace
- 如何使用图片自定义和装饰您的QR码
- xlsx表格怎么做汇总统计_表格进行分类汇总怎么做
- 高数笔记(十九):对面积的曲面积分,对坐标的曲面积分,高斯公式,斯托克斯公式
- 用python读取tif格式图像
- 隔离太无聊!不如用Python实现愤怒的小鸟,看看能否通关!
- Web服务器、应用服务器、数据库服务器之间的关系
- Mip-NeRF 360