当前位置: 首页 > 编程日记 > 正文

Python 中最强大的错误重试库

452a9875ff69337cf7e1b50fc3f468c0.gif

作者 | 费弗里

来源丨Python大数据分析

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()
4300c8adcf7b04b808ae24152cfec162.png

可以看到,我们的函数体内每次生成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()
5fc5b2bd7f0893788868f4ff78484eb9.png

可以看到,我们的函数在限制了最大重试次数后,经过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()
fb56d7135ccb11295e208701db81f87d.png

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()
8272d3fedb30f6583b9fc69dac49fe54.png

可以看到,在上面的演示中,先达到了“最大重试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()
e52ea2d93f035bbc83251d74ece42004.png

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()
c5bb5d2e27316faf1b6f6bf91edfd2ee.png

可以观察到,每一次重试后的等待时长都是随机的~

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
c16f6d266bcecc3c0f2ab6960ee63fe2.pngc4d42146f3700873e42d0e4fe13df355.png

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()
b05c4dde5e9c3e7463a89771e3a3cbe9.png

2.7 对函数的错误重试情况进行统计

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

demo_func9.retry.statistics
0e2935c6a2cca35ba1254a0689a66e9d.png

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


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

3bd26a239b82040d276b6a06a4423631.gif

资讯

留不住客户?从你的系统找原因

资讯

Nginx宣布在俄罗斯禁止贡献

技术

学会用Opencv做贪吃蛇游戏

技术

一行Python代码能干嘛?来看!

5286a00a593526d1c649243d72bfdf7f.png

分享

39aa0c71ac7ddf2a26b3474a9bca9059.png

点收藏

095e1685815150dc6d780123322a2c30.png

点点赞

e13424cb5ef132b358bff207a405c36b.png

点在看

相关文章:

Spring Cloud云架构 - SSO单点登录之OAuth2.0登录流程(2)

上一篇是站在巨人的肩膀上去研究OAuth2.0,也是为了快速帮助大家认识OAuth2.0,闲话少说,我根据框架中OAuth2.0的使用总结,画了一个简单的流程图(根据用户名密码实现OAuth2.0的登录认证): 上面的图…

php的POSIX 函数以及进程测试

参考&#xff1a;http://cn.php.net/manual/zh/ref.posix.php <?phpecho posix_getpid(); //8805sleep(10);?>再用 #ps -ax这个时候如果多开开个浏览器请求&#xff0c;就会发现Apache自动增加了几个新的进程我们发现并非一直请求同一个进程重启apache # /usr/local/ap…

CAS (10) —— JBoss EAP 6.4下部署CAS时出现错误exception.message=Error decoding flow execution的解决办法...

CAS (10) —— JBoss EAP 6.4下部署CAS时出现错误exception.messageError decoding flow execution的解决办法 jboss版本: jboss-eap-6.4-CVE-2015-7501 jdk版本: 1.7.0_79 cas版本: cas 4.1.3 参考来源: Nabble: exception.messageErrordecodingflowexecution Nabble: Caused …

昇思MindSpore1.6发布 AI开发者体验再升级

智能时代&#xff0c;AI技术正在发挥至关重要的作用&#xff0c;而开源的深度学习框架不仅能够降低AI开发者的门槛&#xff0c;而且能够极大节省成本与时间&#xff0c;成为创新的重要推手。2022年3月26-27日&#xff0c;昇思MindSpore TechDay活动线上成功举办&#xff0c;包含…

深入解析:TRUNCATE TABLE 的内部原理解析与恢复思路

摘要 众所周知&#xff0c;truncate table 是一种快速清空表内数据的一种方式&#xff0c;与 delete 方式不同&#xff0c;truncate 只产生非常少的 redo 和 undo&#xff0c;就实现了清空表数据并降低表 HWM 的功能。本文主要围绕 truncate table 的实现原理和 truncate table…

Linux exec与重定向

exec和source都属于bash内部命令&#xff08;builtins commands&#xff09;&#xff0c;在bash下输入man exec或man source可以查看所有的内部命令信息。 bash shell的命令分为两类&#xff1a;外部命令和内部命令。外部命令是通过系统调用或独立的程序实现的&#xff0c;如se…

俄罗斯 Android 系统受限,或将转用 HarmonyOS!

整理 | 郑丽媛出品 | CSDN近一个月来&#xff0c;受当前局势影响&#xff0c;部分底层工具、基础软件、开源项目已相继宣布在俄罗斯停服&#xff0c;期间不少人因此担忧&#xff1a;同出自美国且占据极大智能手机市场的 Android 和 iOS 是否会趁机“作乱”&#xff1f;结果&…

Ios应用网络安全之https

戴维营教育原创文章&#xff0c;转载请注明出处。我们的梦想是做最好的iOS开发培训&#xff01;iOS应用网络安全之HTTPS1. HTTPS/SSL的基本原理安全套接字层 (Secure Socket Layer, SSL) 是用来实现互联网安全通信的最普遍的标准。Web 应用程序使用 HTTPS&#xff08;基于 SSL …

云原生应用的10大关键属性

2019独角兽企业重金招聘Python工程师标准>>> “云原生”是用于描述基于容器的环境的术语&#xff0c;而Kubernetes是一个运行云原生应用程序工作负载的理想平台。 开发人员在设计云原生应用程序时&#xff0c;一定要牢记本文内这10个关键属性&#xff01; “云原生&…

grep 正则表达式及选项以及注意

说明&#xff1a;在原文基础上稍作了修改grep命令简介&#xff1a; 在ex编辑器&#xff08;我没用过&#xff09;中&#xff0c;启动ex编辑器后要查找某个字符串时&#xff0c;在ex的命令提示符后键入::/pattern/p:/g/pattern/pgrep这个名字就由来如此。其中p的含义是print&…

iOS_25彩票_幸运转盘

终于效果图: 各个view的关系图: 背景圆盘(须要扣图处理)LuckyBaseBackground.png 盖在背景圆盘上面的转盘 LuckyRotateWheel.png 代表一个星座或生肖的button背景图片 要创建12个,并以最下方中点为锚点进行旋转 对背景圆盘进行扣图,并在其上面盖上转盘图片的核心代码 在自己定义…

Python 自动化办公之 Excel 对比工具

作者 | 周萝卜来源丨萝卜大杂烩今天我们继续分享真实的自动化办公案例&#xff0c;希望各位 Python 爱好者能够从中得到些许启发&#xff0c;在自己的工作生活中更多的应用 Python&#xff0c;使得工作事半功倍&#xff01;需求由于工作当中经常需要对比前后两个 Excel 文件&am…

jQuery简单实现iframe的高度根据页面内容自适应的方法(转)

本文实例讲述了jQuery简单实现iframe的高度根据页面内容自适应的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;方式1&#xff1a;//注意&#xff1a;下面的代码是放在和iframe同一个页面中调用 $("#iframeId").load(function () {var mainheight $(t…

linux wc 命令简介

此wc命令不是让大家没有食欲的地方。而是linux下一个简单的小命令。NAMEwc — word, line, character, and byte countSYNOPSISwc [-clmw] [file ...]下面让我们来简单的看一下其支持的参数及其代表的含义。 参数及含义 参数含义-c显示文件的Bytes数(字节数)-l将每个文件的行数…

这个插件竟打通了Python和Excel,还能自动生成代码!

作者 | 云朵君来源丨数据STUDIO加载一个Jupyter插件后&#xff0c;无需写代码就能做数据分析&#xff0c;还帮你生成相应代码&#xff1f;没错&#xff0c;只需要加载这个名为Mito的小工具包&#xff0c;用Python做数据分析&#xff0c;变得和用Excel一样简单&#xff1a;介绍以…

集合list set Map问题

2019独角兽企业重金招聘Python工程师标准>>> ####集合list set Map的个人理解 首先集合说的对一类数据的存储容器&#xff0c;对象都是引用类型并不是基本数据类型 collection 接口 list和set都需实现它 collections 抽象了一些集合的基本功能&#xff0c;reverse s…

python学习第四课

#!/user/bin/env python#-*-coding:utf-8-*-# 一、字符串魔法# &#xff08;1&#xff09;.isalpha()是否是字母或汉字。# 例&#xff1a;# a"张san22"# b"张三lisi"# va.isalpha()# v1b.isalpha()# print(v)# print(v1)# 因为a里含有数字&#xff0c;结果…

PHP 截取字符串专题

1. 截取GB2312中文字符串<?php< ?php//截取中文字符串functionmysubstr($str, $start, $len){$tmpstr ""; $strlen $start $len; for($i 0; $i< $strlen; $i){if(ord(substr($str, $i, 1))> 0xa0){$tmpstr. substr($str, $i, 2); $i; }else$tm…

​GPT-3好“搭档”:这种方法缓解模型退化,让输出更自然

作者 | LZM来源丨数据实战派文本生成对于许多自然语言处理应用来说都是非常重要的。但神经语言模型的基于最大化的解码方法&#xff08;如 beam search&#xff09;往往导致退化解&#xff0c;即生成的文本是不自然的&#xff0c;并且常常包含不必要的重复。现有的方法通过采样…

(Question)CSS中position的绝对定位问题

RT,绝对定位相对于定位的元素存在是哪里&#xff1f; https://yunpan.cn/crjSMTiak2srZ 访问密码 1570转载于:https://www.cnblogs.com/LiuChunfu/p/5139958.html

BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)

题目描述 Bob有一棵 nn 个点的有根树&#xff0c;其中1号点是根节点。Bob在每个点上涂了颜色&#xff0c;并且每个点上的颜色不同。 定义一条路径的权值是&#xff1a;这条路径上的点&#xff08;包括起点和终点&#xff09;共有多少种不同的颜色。 Bob可能会进行这几种操作&am…

ls -l |wc -l命令多统计一行

#ls -l |wc -l注意&#xff1a;总用量也占用1行&#xff0c;所以统计出来的是14而不是13其他网友提醒 #ls -l |wc -l 就统计实际的行&#xff0c;放大就看出效果1和l不同

驱动数字经济加速,摩尔线程发布全新元计算架构MUSA和GPU产品

2022年3月30日&#xff0c;北京——摩尔线程今天举行主题为“元动力 创无限”的春季发布会。摩尔线程创始人兼CEO张建中解读了“元计算”这一产业趋势&#xff0c;并发布全新架构及系列重磅新品&#xff0c;包括&#xff1a;MUSA&#xff08;Moore Threads Unified System Arch…

HDU 4869 Turn the pokers(思维+组合公式+高速幂)

Turn the pokers 大意&#xff1a;给出n次操作&#xff0c;给出m个扑克。然后给出n个操作的个数a[i]&#xff0c;每一个a[i]代表能够翻的扑克的个数&#xff0c;求最后可能出现的扑克的组合情况。Hint Sample Input&#xff1a; 3 3 3 2 3 For the this example: 0 express fac…

马云打响本地生活消费攻坚战,饿了么获手淘一级入口,美团危险了

8月2日&#xff0c;细心的网友可以发现&#xff0c;手机淘宝App首页已上线“饿了么外卖”&#xff0c;饿了么成为手机淘宝首页的10个默认入口之一。这也就意味着以后手机淘宝用户可以通过淘宝首页新入口进入外卖服务&#xff0c;在应用内直接完成由饿了么提供的订餐外卖服务。 …

Linux文件,文件描述符以及dup()和dup2()

一.Linux中文件 可以分为4种&#xff1a;普通文件、目录文件、链接文件和设备文件。1、普通文件是用户日常使用最多的文件&#xff0c;包括文本文件、shell脚本、二进制的可执行和各种类型的数据。ls -lh 来查看某个文件的属性&#xff0c;可以看到有类似 -rw-r--r-- &#xff…

摩尔线程推出首款数据中心级全栈功能GPU:MTT S2000

2022年3月30日&#xff0c;北京——摩尔线程正式推出首款基于其先进架构MUSA统一系统架构&#xff08;Moore Threads Unified System Architecture&#xff09;打造的数据中心级多功能GPU产品MTT S2000。摩尔线程MTT S2000基于其第一代MUSA架构GPU芯片苏堤研发制成&#xff0c;…

jquery 获取 outerHtml 包含当前节点本身的代码

在开发过程中&#xff0c;jQuery.html() 是获取当前节点下的html代码&#xff0c;并不包含当前节点本身的代码&#xff0c;然后我们有时候确需要&#xff0c;找遍jQuery api文档也没有任何方法可以拿到。 看到有的人通过parent().html()&#xff0c;如果当前元素没有兄弟元素还…

修改CentOS yum源

解决在CentOS yum源下载慢的办法最近在虚拟机下面安装了个CentOS 5.5&#xff0c;使用yum更新时发现下载速度异常慢。可以修改yum的配置文件&#xff0c;把其镜像指向国内的服务器即可。 方案一&#xff1a; # cd /etc/yum.repos.d/ # mv CentOS-Base.repo CentOS-Base.repo.b…

带monkey的测流量!

为什么80%的码农都做不了架构师&#xff1f;>>> //public static void flow(){ //String command1 "adb shell monkey -p com.netease.newsreader.activity -s 500 -v 2000"; //String command2 "adb shell ps"; //String str"com.nete…