当前位置: 首页 > 后端技术 > Python

Python中最强大的错误重试库

时间:2023-03-26 13:21:29 Python

1简介我们在编写程序,尤其是与网络请求相关的程序时,比如调用网页界面,运行网络爬虫等任务,经常会遇到一些偶然的请求失败,此时,如果简单地捕获错误然后跳过相应的任务,肯定是不严谨的,尤其是在网络爬虫中,会有丢失有价值数据的风险。在这种情况下,我们非常有必要在我们的程序逻辑中加入一些“错误重试”的策略。费老师,几年前我写过一篇介绍Python中retry库的文章,但是功能单一,只能满足基本需求。今天要给大家介绍的tenacity库,可能是目前Python生态中最好的错误重试库。来看看它的主要功能吧~2tenacity中的常用功能作为第三方Python库,我们可以使用pipinstalltenacity来安装。安装完成后,我们来了解一下tenacity的主要使用方法和特点:2.1tenacity基础使用tenacity错误重试的核心功能是通过其retry装饰器实现的,默认是关闭的。给重试装饰器传递参数时,当它装饰的函数抛出错误时,它会一直重试,比如下面这个简单的例子:importrandomfromtenacityimportretry@retrydefdemo_func1():a=random.random()print(a)ifa>=0.1:raiseExceptiondemo_func1()可以看出我们的函数体每次都会产生一个0到1之间的随机数,当随机数不超过0.1时就会停止抛出错误,否则韧度会catch每个错误抛出行为并立即重试。2.2设置最大重试次数有时候我们对于重试某个函数逻辑错误的容忍度是有限的。比如我们调用某个网络接口的时候,如果连续n次执行失败,我们可能会认为这个任务本身存在缺陷,哪天重试就不正常了。这时候,我们可以使用tenacity中的stop_after_attempt函数作为retry()中的停止参数,为我们的“无休止”错误重试过程添加一个终点,其中stop_after_attempt()接受一个整数输入作为“最大重试次数”“Try"times:fromtenacityimportretry,stop_after_attempt@retry(stop=stop_after_attempt(3))defdemo_func2():print('functionexecution')raiseExceptiondemo_func2()可以看出我们的函数限制了最大权重数之后oftrials,经过3次重试,第4次继续执行后仍然报错,正式抛出函数中对应的Exception错误,结束重试过程。2.3设置重试的最大超时时间除了上一节设置最大错误重试次数外,tenacity还为我们提供了stop_after_delay()函数来设置整个重试过程的最大耗时。它会结束重试过程:importtimefromtenacityimportretry,stop_after_delay#设置最大重试超时为5秒@retry(stop=stop_after_delay(5))defdemo_func3():time.sleep(1)print(f'haspassed{time.time()-start_time}seconds')raiseException#记录开始时间start_time=time.time()demo_func3()2.4组合重试停止条件如果我们的任务需要加上最大重试次数和最大超时时长限制同时,在坚韧中,你只需要使用|运算符组合不同的约束,然后传入retry()的停止参数。比如下面的例子,当我们的函数重试超过3秒或者重试次数大于5次的时候,就可以结束重试:(3)|stop_after_attempt(5)))defdemo_func4():time.sleep(random.random())'print({time.time()-start_time}secondshaveelapsed')raiseException#记录开始时间start_time=time.time()demo_func4()可以看到,在上面的demo中,首先达到了“最多重试5次”的限制,从而结束了重试过程。2.5设置相邻重试的时间间隔在某些情况下,我们不希望每次重试抛出错误后立即开始下一次重试。比如为了在爬虫任务中更好的伪装我们的程序,在tenacity中提供了一系列非常实用的函数,配合retry()的wait参数,帮助我们妥善处理相邻重试的时间间隔。比较实用的方法如下:2.5.1设置一个固定的时间间隔我们通过在tenacity中使用wait_fixed(),可以在相邻的重试之间设置一个以秒为单位的固定等待间隔,如下简单的例子:importtimefromtenacityimportretry,wait_fixed,stop_after_attempt#设置重试等待间隔为1秒@retry(wait=wait_fixed(1),stop=stop_after_attempt(3))defdemo_func5():print(f'{time.time()-start_time}secondshavepassed')raiseException#记录开始时间start_time=time.time()demo_func5()2.5.2设置随机时间间隔除了设置固定的时间间隔,tenacity还可以通过wait_random()帮我们为相邻的重试设置一个均匀分布的随机数,只需要设置均匀分布的范围即可。可用:importtimefromtenacityimportretry,wait_random,stop_after_attempt#设置重试等待间隔为1到3之间的随机数@retry(wait=wait_random(min=1,max=3),stop=stop_after_attempt(5))defdemo_func6():print(f'{time.time()-start_time}secondshaveelapsed')raiseException#记录开始时间start_time=time.time()demo_func6()可以观察每次重试后的等待时间都是随机的~2.6自定义是否触发重试tenacity中retry()的默认策略是当它装饰的函数在执行过程中“throwsanyerror”时重试,但是在某些情况下,我们需要的可能是捕获/忽略特定的错误类型,或者捕获异常的计算结果Tenacity也内置了相关的实用函数:2.6.1捕获或忽略特定的错误类型在tenacity中使用retry_if_exception_type()和retry_if_not_exception_type(),配合retry()的重试参数,我们可以捕获或忽略特定的错误类型忽略:fromtenacity导入retry,retry_if_expection_type,retry_if_not_expection_type@retry(retry=retry_if_if_expection_expection_type(fileexistSisterRor))defdemo_func7():retry_exectrunl=retry_not_exect_expectrund2reprentrund.firnyfirentfirentfirentfillentfimortery定义可以额外编写条件判断函数,在韧劲中配合retry_if_result(),实现对函数返回结果的自定义条件判断。只有返回True时才会触发重试操作:importrandomfromtenacityimportretry,retry_if_result@retry(retry=retry_if_result(lambdax:x>=0.1))defdemo_func9():a=random.random()print(a)returna#recordstarttimedemo_func9()2.7用于统计函数的错误重试对于被tenacity的retry()修饰的函数,我们可以打印其retry.statistics属性来查看错误重试统计记录结果。比如这里我们打印前面执行的示例函数demo_func9()的统计结果:demo_func9.retry.statistics除了上面的功能,tenacity还有很多特殊的功能,可以和logging模块,异步函数,coroutines结合使用和其他Python函数来实现更高级的功能。感兴趣的朋友可以去https:///github.com/jd/tenacity了解更多以上就是本次分享的全部内容。觉得文章还不错的话,请关注公众号:Python编程学习圈,每日干货分享,发送“J”还能收到海量学习资料,涵盖Python电子书、教程、数据库编程,Django,爬虫,云计算等。或者去编程学习网了解更多编程技术知识。