1简介 我们在编写程序尤其是与网络请求相关的程序,如调用web接口、运行网络爬虫等任务时,经常会遇到一些偶然发生的请求失败的状况,这种时候如果我们仅仅简单的捕捉错误然后跳过对应任务,肯定是不严谨的,尤其是在网络爬虫中,会存在损失有价值数据的风险。 这类情况下我们就很有必要为我们的程序逻辑添加一些错误重试的策略,费老师我在几年前写过文章介绍过Python中的retry库,但它功能较为单一,只能应对基本的需求。 而今天我要给大家介绍的tenacity库,可能是目前Python生态中最好用的错误重试库,下面就让我们一睹其主要功能吧 2tenacity中的常用功能 作为一个第三方Python库,我们可以使用pipinstalltenacity对其进行安装,安装完成后,下面我们来学习一下tenacity的主要使用方法和特性: 2。1tenacity的基础使用 tenacity的错误重试核心功能由其retry装饰器来实现,默认不给retry装饰器传参数时,它会在其所装饰的函数运行过程抛出错误时不停地重试下去,譬如下面这个简单的例子:importrandom fromtenacityimportretry retry defdemofunc1: arandom。random print(a) ifa0。1: raiseException demofunc1 可以看到,我们的函数体内每次生成0到1之间的随机数,当这个随机数不超过0。1时才会停止抛出错误,否则则会被tenacity捕捉到每次的错误抛出行为并立即重试。 2。2设置最大重试次数 有些时候我们对某段函数逻辑错误重试的忍耐是有限度的,譬如当我们调用某个网络接口时,如果连续n次都执行失败,我们可能就会认为这个任务本身就存在缺陷,不是通过重试就能有朝一日正常的。 这种时候我们可以利用tenacity中的stopafterattempt函数,作为retry中的stop参数传入,从而为我们无尽的错误重试过程添加一个终点,其中stopafterattempt接受一个整数输入作为最大重试的次数:fromtenacityimportretry,stopafterattempt retry(stopstopafterattempt(3)) defdemofunc2: print(函数执行) raiseException demofunc2 可以看到,我们的函数在限制了最大重试次数后,经过3次重试,在第4次继续执行依然抛出错误后,正式地抛出了函数中对应的Exception错误结束了重试过程。 2。3设置重试最大超时时长 我们除了像上一小节中那样设置最大错误重试的次数之外,tenacity还为我们提供了stopafterdelay函数来设置整个重试过程的最大耗时,超出这个时长也会结束重试过程:importtime fromtenacityimportretry,stopafterdelay 设置重试最大超时时长为5秒 retry(stopstopafterdelay(5)) defdemofunc3: time。sleep(1) print(f已过去{time。timestarttime}秒) raiseException 记录开始时间 starttimetime。time demofunc3 2。4组合重试停止条件 如果我们的任务同时需要添加最大重试次数以及最大超时时长限制,在tenacity中仅需要用运算符组合不同的限制条件再传入retry的stop参数即可,譬如下面的例子,当我们的函数执行重试超过3秒或次数大于5次时均可以结束重试:importtime importrandom fromtenacityimportretry,stopafterdelay,stopafterattempt retry(stop(stopafterdelay(3)stopafterattempt(5))) defdemofunc4: time。sleep(random。random) print(f已过去{time。timestarttime}秒) raiseException 记录开始时间 starttimetime。time demofunc4 可以看到,在上面的演示中,先达到了最大重试5次的限制从而结束了重试过程。 2。5设置相邻重试之间的时间间隔 有些情况下我们并不希望每一次重试抛出错误后,立即开始下一次的重试,譬如爬虫任务中为了更好地伪装我们的程序,tenacity中提供了一系列非常实用的函数,配合retry的wait参数,帮助我们妥善处理相邻重试之间的时间间隔,其中较为实用的主要有以下两种方式: 2。5。1设置固定时间间隔 我们通过使用tenacity中的waitfixed可以为相邻重试之间设置固定的等待间隔秒数,就像下面的简单示例那样:importtime fromtenacityimportretry,waitfixed,stopafterattempt 设置重试等待间隔为1秒 retry(waitwaitfixed(1),stopstopafterattempt(3)) defdemofunc5: print(f已过去{time。timestarttime}秒) raiseException 记录开始时间 starttimetime。time demofunc5 2。5。2设置随机时间间隔 除了设置固定的时间间隔外,tenacity还可以通过waitrandom帮助我们为相邻重试设置均匀分布随机数,只需要设置好均匀分布的范围即可:importtime fromtenacityimportretry,waitrandom,stopafterattempt 设置重试等待间隔为1到3之间的随机数 retry(waitwaitrandom(min1,max3),stopstopafterattempt(5)) defdemofunc6: print(f已过去{time。timestarttime}秒) raiseException 记录开始时间 starttimetime。time demofunc6 可以观察到,每一次重试后的等待时长都是随机的 2。6自定义是否触发重试 tenacity中retry的默认策略是当其所装饰的函数执行过程抛出任何错误时即进行重试,但有些情况下我们需要的可能是对特定错误类型的捕捉忽略,亦或是对异常计算结果的捕捉。 tenacity中同样内置了相关的实用功能: 2。6。1捕捉或忽略特定的错误类型 使用tenacity中的retryifexceptiontype和retryifnotexceptiontype,配合retry的retry参数,我们可以对特定的错误类型进行捕捉或忽略:fromtenacityimportretry,retryifexceptiontype,retryifnotexceptiontype retry(retryretryifexceptiontype(FileExistsError)) defdemofunc7: raiseTimeoutError retry(retryretryifnotexceptiontype(FileNotFoundError)) defdemofunc8: raiseFileNotFoundError 2。6。2自定义函数结果条件判断函数 我们可以编写额外的条件判断函数,配合tenacity中的retryifresult,实现对函数的返回结果进行自定义条件判断,返回True时才会触发重试操作:importrandom fromtenacityimportretry,retryifresult retry(retryretryifresult(lambdax:x0。1)) defdemofunc9: arandom。random print(a) returna 记录开始时间 demofunc9 2。7对函数的错误重试情况进行统计 被tenacity的retry装饰的函数,我们可以打印其retry。statistics属性查看其历经的错误重试统计记录结果,譬如这里我们对前面执行过的示例函数demofunc9的统计结果进行打印:demofunc9。retry。statistics 本文示例代码及文件已上传至https:github。comCNFefferyDataScienceStudyNotes 以上就是本文的全部内容,欢迎在评论区与我进行讨论