本文示例代码及文件已上传至我的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 自定义是否触发重试

tenacityretry()的默认策略是当其所装饰的函数执行过程“抛出任何错误”时即进行重试,但有些情况下我们需要的可能是对特定错误类型的捕捉/忽略,亦或是对异常计算结果的捕捉。

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 对函数的错误重试情况进行统计

tenacityretry()装饰的函数,我们可以打印其retry.statistics属性查看其历经的错误重试统计记录结果,譬如这里我们对前面执行过的示例函数demo_func9()的统计结果进行打印:

demo_func9.retry.statistics

除了上述的功能之外,tenacity还具有很多特殊的特性,可以结合logging模块、异步函数、协程等其他Python功能实现更高级的功能,感兴趣的朋友可以前往https://github.com/jd/tenacity了解更多。


以上就是本文的全部内容,欢迎在评论区与我进行讨论~

觉得还不错就给我一个小小的鼓励吧!

Python中最强大的错误重试库相关推荐

  1. Python 中最强大的错误重试库

    作者 | 费弗里 来源丨Python大数据分析 1 简介 我们在编写程序尤其是与网络请求相关的程序,如调用web接口.运行网络爬虫等任务时,经常会遇到一些偶然发生的请求失败的状况,这种时候如果我们仅仅 ...

  2. 小结两种在Python中导入C语言扩展库的方法

    小结两种在Python中导入C语言扩展库的方法 分类: Pythoner2009-08-18 20:44 2563人阅读 评论(1) 收藏 举报 python扩展c语言importstring 一种是 ...

  3. python一直报缩进错误_如何避免Python中的缩进错误

    Python是当今编程界领先和新兴的编程平台之一.凭借其丰富的功能和巨大的灵活性,人们可以在这个平台上实现很多,只要他们知道如何操作它.在Python中的这个缩进错误中,我们将介 Python是当今编 ...

  4. 成功解决Python中导出图片出现错误SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position

    成功解决Python中导出图片出现错误SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position ...

  5. linux 下的动态库制作 以及在python 中如何调用 c 函数库

    linux 下的动态库制作 以及在python 中如何调用 c 函数库 动态库: 动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序 ...

  6. 【Python中的权限错误:无法访问文件】-- 解决方案

    [Python中的权限错误:无法访问文件]-- 解决方案 在Python编程过程中,我们常常会遇到文件读写.创建.删除等操作.有时候当我们试图进行这些操作时,会出现"PermissionEr ...

  7. 捋一捋Python中的数学运算math库(上篇)

    正式的Python专栏第18篇,同学站住,别错过这个从0开始的文章! 很多学习编程的都多多少少学习了一些数学知识. 学委之前也简单吐槽了 Python中奇葩的round函数! 这篇我们讲讲那些常用的数 ...

  8. 关于python语言下列说法错误的是_在Python中下列说法错误的是()

    在Python中下列说法错误的是() 答:Python语言只能用4个空格的缩进来实现程序的强制可读性 比赛中,运动员击出的球压在端线上,则判该运动员失分 答:× 虚证的症状表现是( ) 答:神疲乏力 ...

  9. Python 中 xpath 语法 与 lxml 库解析 HTML/XML 和 CSS Selector

    The lxml.etree Tutorial :https://lxml.de/tutorial.html python3 解析 xml:https://www.cnblogs.com/deadwo ...

  10. python中的eof错误_python – 解析器YACC中的EOF错误

    我试图使用PLY库中为Python提供的yacc解析器来解析字符串. 解析器本身很长,但我遇到的问题是它总是给我同样的错误,无论我放什么样的字符串. 错误是这样的: yacc:输入中的解析错误. EO ...

最新文章

  1. fileinput_open_读写文件_python
  2. C#中equal与==的区别
  3. DJANGO用户名认证一例
  4. 实验四+149+肖雷
  5. 程序员成长之路 java面试指导(作者说的极好要看) 静下心看
  6. php5.3+for+linux,Centos 安装 nginx + php5.3
  7. 关于Spring注解开发教程,打包全送你
  8. adb shell操作文件
  9. 面试突击41:notify是随机唤醒吗?
  10. Android内存优化12 内存泄漏常见情况3 注册泄漏
  11. Mac 更新系统后无法使用git
  12. Scrum板与Kanban如何抉择?敏捷工具:otmic板与按照mtygdmam
  13. linux开机启动任务和定时执行任务
  14. 【新手】关于路径格式的问题(错误提示incomplete universal character name)
  15. Lisp语言:列表(List)
  16. 轻松可视化实现设备监控大屏效果
  17. win10台式机一根网线连接笔记本wifi网络
  18. logitech g27 matlab,HiPole 模拟赛车入门神器Logitech G27测评
  19. 把jpg转换成pdf教程
  20. 基于SpringBoot的高校在线答疑管理系统

热门文章

  1. HarmonyOS resources目录中“限定词目录”命名要求
  2. (java中的super)不会飞还能叫Superman吗
  3. jsp异常 The JSP specification requires that an attribute name is preceded by whitespace
  4. 如何使用图片自定义和装饰您的QR码
  5. xlsx表格怎么做汇总统计_表格进行分类汇总怎么做
  6. 高数笔记(十九):对面积的曲面积分,对坐标的曲面积分,高斯公式,斯托克斯公式
  7. 用python读取tif格式图像
  8. 隔离太无聊!不如用Python实现愤怒的小鸟,看看能否通关!
  9. Web服务器、应用服务器、数据库服务器之间的关系
  10. Mip-NeRF 360