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

如何在Python中优雅地重试

时间:2023-03-26 18:55:02 Python

在编码中,一些涉及网络连接的代码片段经常需要重试。本文将一步步讲解如何实现一个优雅的重试装饰器以及tenacity库的使用。如果原版本v0.0中有如下函数,该函数有一些建立网络连接的逻辑deff():#dosomeconnectionsreturn0为了避免偶尔的网络连接失败,需要重试机制添加,那么最简单的形式就是在相应的代码片段中添加一个循环,在循环体中使用异常捕获,连接成功则退出循环,否则重复相关逻辑。此时修改后的函数f如下deff():while1:try:#dosomeconnectionsbreakexceptConnectionError:continuereturn0装饰器版本v1.0可以使用装饰器来抽象代码。比如现在有两个函数f1和f2需要添加重试机制,写一个装饰器函数retry,用它来装饰f1和f2。这样就避免了对旧代码的修改,也实现了代码复用。例子如下defretry(f):defwrap(*args,**kwargs):while1:try:returnf(*args,**kwargs)exceptConnectionError:continuereturnwrap@retry()deff1():#dosomeconnectionsreturn0@retry()deff2():#dosomeotherconnectionsreturn0decoratorversionv1.1v1.0withparameters重试装饰器还有一些问题,如果有些函数要重试3次,有的要重试5次,重试间隔也根据不同的功能不同,v1.0无法实现。这时候可以使用带参数的三层装饰器,比如下面代码实现的retry装饰器,可以传入times和interval这两个参数来设置重试次数和重试间隔defretry(times,interval):defretry(f)defwrap(*args,**kwargs):whiletimes:try:returnf(*args,**kwargs)exceptConnectionError:times-=1time.sleep(interval)继续返回wrapreturndecorator#retry3timeswithanintervalof10seconds@retry(times=3,interval=10)deff1():#做一些连接return0#Retry5timeswith15seconds@retry(times=5、interval=15)deff2():#dosomeotherconnectionsreturn0装饰器支持参数后,可以根据需要定义更丰富的参数,比如通过参数设置需要捕获哪些异常。tenacityversiontenacity是第三方开源重试函数库。其实它的作用和原理和上面写的代码差不多!只是它有更多可定义的参数。如果不想重新发明轮子,可以直接使用。代码示例如下fromtenacityimportretry,stop_after_attempt,wait_fixed#Retrywithoutanyparameters@retrydeff():#dosomeconnectionsreturn0#Retry5timeswith15seconds@retry(stop=stop_after_attempt(5),wait=wait_fixed(15))deff():#做一些连接return0