python中可以發(fā)生異常自動(dòng)重試庫retrying
1、前言
在我們?nèi)粘5拈_發(fā)工作中,為了代碼的健壯性,我們通常會(huì)對(duì)方法中的業(yè)務(wù)代碼進(jìn)行try-except的包裝,以防止在發(fā)生異常的時(shí)候進(jìn)程被中斷。如果發(fā)生異常,我們?cè)撛趺崔k呢?有同學(xué)可能用自己的方式(循環(huán))去做了重試,那么有沒有一種通用的可靠的重試方式呢?答案是有的,它就是retrying庫,今天我們就一起來看看。
2、快速開始
retrying是一個(gè)極簡的使用Python編寫的,擁有1.8k??的可以實(shí)現(xiàn)方法異常重試的庫,我們?cè)趯?shí)際使用中直接為我們的方法增加一個(gè)@retry的裝飾器即可。
2.1、安裝retrying
pip install retrying
2.2、模擬無限重試
假設(shè)我們現(xiàn)在有一個(gè)方法demo1,這個(gè)方法中調(diào)用了另一個(gè)接口e1,但是被調(diào)用的這個(gè)e1接口不穩(wěn)定,當(dāng)e1接口返回異常的時(shí)候,我們需要去重試。
from retrying import retry
import time
?
# 一個(gè)會(huì)返回異常的接口e1
def e1():
? ?time.sleep(1)
? ?print('err')
? ?# 我們拋出異常模擬接口異常
? ?raise TypeError
?
# 全局計(jì)數(shù)器
a=1
@retry
def demo1(n):
? ?# 方法中調(diào)用全局變量,需要global
? ?global a
? ?# 進(jìn)行try-except
? ?try:
? ? ? ?print(f'開始嘗試!{a}')
? ? ? ?a+=1
? ? ? ?e1()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?# 當(dāng)重試完成后還未成功,則返回超時(shí)
? ? ? ?raise TimeoutError
if __name__=='__main__':
? ?demo1(0)代碼執(zhí)行結(jié)果:

你會(huì)發(fā)現(xiàn),我們代碼會(huì)一值被重試,這是為什么呢?
默認(rèn)的retry裝飾器就是無限重試的,直到重試成功為止。因?yàn)槲覀兊慕涌趀1是永遠(yuǎn)返回異常的,所以這個(gè)重試將會(huì)永遠(yuǎn)持續(xù)下去。
我們改造e1方法如下,即可在重試第10次成功:
# 一個(gè)會(huì)返回異常的接口e1
def e1():
? ?time.sleep(1)
? ?print('err')
? ?# 當(dāng)重試次數(shù)達(dá)到10時(shí),返回True
? ?if a>=10:
? ? ? ?print('ok!')
? ? ? ?return True
? ?# 我們拋出異常模擬接口異常
? ?raise TypeError代碼執(zhí)行結(jié)果:
開始嘗試!1
err
開始嘗試!2
err
開始嘗試!3
err
開始嘗試!4
err
開始嘗試!5
err
開始嘗試!6
err
開始嘗試!7
err
開始嘗試!8
err
開始嘗試!9
err
ok!
2.3、模擬最大重試次數(shù)
上面的無限重試明顯在實(shí)際業(yè)務(wù)場景中適用面不是非常廣,當(dāng)我們需要使用重試次數(shù)來限制時(shí),我們就可以使用retry的裝飾器參數(shù)stop_max_attempt_number來實(shí)現(xiàn)。
# 全局計(jì)數(shù)器
a=1
@retry(stop_max_attempt_number=3)
def demo1(n):
? ?# 方法中調(diào)用全局變量,需要global
? ?global a
? ?# 進(jìn)行try-except
? ?try:
? ? ? ?print(f'開始嘗試!{a}')
? ? ? ?a+=1
? ? ? ?e1()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?# 當(dāng)重試完成后還未成功,則返回超時(shí)
? ? ? ?raise TimeoutError以上代碼表示,我們只重試3次,如果還未成功,則返回超時(shí)異常。
代碼執(zhí)行結(jié)果:

2.4、模擬最大重試時(shí)間
除了可以使用重試次數(shù)限制外,當(dāng)我們對(duì)時(shí)間要求比較明確的時(shí)候,我們就可以使用stop_max_delay參數(shù)來指定最大重試時(shí)間。這個(gè)參數(shù)的單位是ms。
# 全局計(jì)數(shù)器
a=1
@retry(stop_max_delay=2000)
def demo1(n):
? ?# 方法中調(diào)用全局變量,需要global
? ?global a
? ?# 進(jìn)行try-except
? ?try:
? ? ? ?print(f'開始嘗試!{a}')
? ? ? ?a+=1
? ? ? ?e1()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?# 當(dāng)重試完成后還未成功,則返回超時(shí)
? ? ? ?raise TimeoutError如上代碼表示,當(dāng)重試時(shí)間超過2s就會(huì)拋出超時(shí)異常。因?yàn)樵趀1方法中,每次調(diào)用都會(huì)休眠1s,所以對(duì)于限制兩秒,我們只能在2s內(nèi)重試2次。
代碼執(zhí)行結(jié)果:

2.5、模擬重試間隔時(shí)間
當(dāng)我們不希望重試間隔時(shí)間太長的時(shí)候,我們可以使用參數(shù)wait_fixed指定重試的間隔時(shí)間。
# 全局計(jì)數(shù)器
a=1
@retry(stop_max_delay=6000,wait_fixed=1000)
def demo1(n):
? ?# 方法中調(diào)用全局變量,需要global
? ?global a
? ?# 進(jìn)行try-except
? ?try:
? ? ? ?print(f'開始嘗試!{a}')
? ? ? ?a+=1
? ? ? ?e1()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?# 當(dāng)重試完成后還未成功,則返回超時(shí)
? ? ? ?raise TimeoutError如上代碼表示最大重試時(shí)間6秒,重試間隔1秒,但是e1方法中還休眠了1秒,所以在6秒內(nèi),我們理論上只能重試4次(不是3次)。
代碼運(yùn)行結(jié)果:

在此基礎(chǔ)上,retrying還為我們提供了隨機(jī)的重試間隔時(shí)間參數(shù)。
- wait_random_min,重試間隔最小時(shí)間
- wait_random_max,重試間隔最大時(shí)間
一般,這兩個(gè)參數(shù)都是成對(duì)出現(xiàn),用于限制重試間隔時(shí)間的范圍。
2.6、指定重試調(diào)用的方法
retrying允許我們?cè)谥卦嚨耐瑫r(shí)去調(diào)用一個(gè)方法。使用參數(shù)stop_func來指定這個(gè)方法名。
# attempts, delay這兩個(gè)參數(shù)是必填的
def stop_f(attempts, delay):
? ?print('發(fā)生異常了,正在進(jìn)行重試!')
# 全局計(jì)數(shù)器
a=1
@retry(stop_func=stop_f,stop_max_delay=3)
def demo1(n):
? ?# 方法中調(diào)用全局變量,需要global
? ?global a
? ?# 進(jìn)行try-except
? ?try:
? ? ? ?print(f'開始嘗試!{a}')
? ? ? ?a+=1
? ? ? ?e1()
? ?except Exception as e:
? ? ? ?print(e)
? ? ? ?# 當(dāng)重試完成后還未成功,則返回超時(shí)
? ? ? ?raise TimeoutError代碼運(yùn)行結(jié)果:

但是stop_func存在一個(gè)問題就是和stop_max_delay、stop_max_attempt_number結(jié)合使用的時(shí)候,后面兩者會(huì)失效。
2.7、指定重試的異常類型
當(dāng)我們需要針對(duì)特定的異常才進(jìn)行重試時(shí),就需要用到這個(gè)參數(shù):retry_on_exception。
2.8、指定重試的特定條件
當(dāng)達(dá)到某個(gè)條件才會(huì)進(jìn)行重試,需要使用參數(shù):retry_on_result。
到此這篇關(guān)于python中可以發(fā)生異常自動(dòng)重試庫retrying的文章就介紹到這了,更多相關(guān)python retrying內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Django Rest Framework框架構(gòu)建復(fù)雜API技能詳解
這篇文章會(huì)詳細(xì)介紹Django REST Framework的核心組成部分,包括Serializers、ViewSets、Routers、權(quán)限和認(rèn)證系統(tǒng)以及測試和調(diào)試工具,文章從基礎(chǔ)開始,逐步深入,旨在幫助讀者掌握使用Django REST Framework構(gòu)建復(fù)雜API的技能2023-09-09
一文深入了解Python中的繼承知識(shí)點(diǎn)
Python?是面向?qū)ο蟮木幊陶Z言,因此支持面向?qū)ο蟮娜筇匦灾唬豪^承。本文就帶大家了解了解Python中繼承的相關(guān)知識(shí)點(diǎn),感興趣的可以了解一下2022-11-11
python在windows和linux下獲得本機(jī)本地ip地址方法小結(jié)
這篇文章主要介紹了python在windows和linux下獲得本機(jī)本地ip地址方法,實(shí)例分析了Python獲得IP地址的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
使用 Python 列出串口的實(shí)現(xiàn)方法
有時(shí)在編程時(shí),我們需要獲取有關(guān)系統(tǒng)中可用通信端口的信息, 我們將討論如何使用 Python 來做到這一點(diǎn),將討論使用串口或 com 端口的通信, 我們將深入探索 Python 包,以幫助我們獲得系統(tǒng)的可用通信端口,感興趣的朋友一起看看吧2023-08-08
Python爬取十篇新聞統(tǒng)計(jì)TF-IDF
這篇文章主要為大家詳細(xì)介紹了Python爬取十篇新聞統(tǒng)計(jì)TF-IDF的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
跨平臺(tái)python異步回調(diào)機(jī)制實(shí)現(xiàn)和使用方法
這篇文章主要介紹了python異步回調(diào)機(jī)制的實(shí)現(xiàn)方法,提供了使用方法代碼2013-11-11
利用python讀取YUV文件 轉(zhuǎn)RGB 8bit/10bit通用
今天小編就為大家分享一篇利用python讀取YUV文件 轉(zhuǎn)RGB 8bit/10bit通用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12
Python中l(wèi)ambda的用法及其與def的區(qū)別解析
這篇文章主要介紹了Python中l(wèi)ambda的用法及其與def的區(qū)別解析,需要的朋友可以參考下2014-07-07

