日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

python中可以發生異常自動重試庫retrying_python

作者:??Python研究所???? ? 更新時間: 2022-08-04 編程語言

1、前言

在我們日常的開發工作中,為了代碼的健壯性,我們通常會對方法中的業務代碼進行try-except的包裝,以防止在發生異常的時候進程被中斷。如果發生異常,我們該怎么辦呢?有同學可能用自己的方式(循環)去做了重試,那么有沒有一種通用的可靠的重試方式呢?答案是有的,它就是retrying庫,今天我們就一起來看看。

2、快速開始

retrying是一個極簡的使用Python編寫的,擁有1.8k??的可以實現方法異常重試的庫,我們在實際使用中直接為我們的方法增加一個@retry的裝飾器即可。

2.1、安裝retrying

pip install retrying

2.2、模擬無限重試

假設我們現在有一個方法demo1,這個方法中調用了另一個接口e1,但是被調用的這個e1接口不穩定,當e1接口返回異常的時候,我們需要去重試。

from retrying import retry
import time
?
# 一個會返回異常的接口e1
def e1():
 ? ?time.sleep(1)
 ? ?print('err')
 ? ?# 我們拋出異常模擬接口異常
 ? ?raise TypeError
?
# 全局計數器
a=1
@retry
def demo1(n):
 ? ?# 方法中調用全局變量,需要global
 ? ?global a
 ? ?# 進行try-except
 ? ?try:
 ? ? ? ?print(f'開始嘗試!{a}')
 ? ? ? ?a+=1
 ? ? ? ?e1()
 ? ?except Exception as e:
 ? ? ? ?print(e)
 ? ? ? ?# 當重試完成后還未成功,則返回超時
 ? ? ? ?raise TimeoutError
if __name__=='__main__':
 ? ?demo1(0)

代碼執行結果:

你會發現,我們代碼會一值被重試,這是為什么呢?

默認的retry裝飾器就是無限重試的,直到重試成功為止。因為我們的接口e1是永遠返回異常的,所以這個重試將會永遠持續下去。

我們改造e1方法如下,即可在重試第10次成功:

# 一個會返回異常的接口e1
def e1():
 ? ?time.sleep(1)
 ? ?print('err')
 ? ?# 當重試次數達到10時,返回True
 ? ?if a>=10:
 ? ? ? ?print('ok!')
 ? ? ? ?return True
 ? ?# 我們拋出異常模擬接口異常
 ? ?raise TypeError

代碼執行結果:

開始嘗試!1
err
開始嘗試!2
err
開始嘗試!3
err
開始嘗試!4
err
開始嘗試!5
err
開始嘗試!6
err
開始嘗試!7
err
開始嘗試!8
err
開始嘗試!9
err
ok!

2.3、模擬最大重試次數

上面的無限重試明顯在實際業務場景中適用面不是非常廣,當我們需要使用重試次數來限制時,我們就可以使用retry的裝飾器參數stop_max_attempt_number來實現。

# 全局計數器
a=1
@retry(stop_max_attempt_number=3)
def demo1(n):
 ? ?# 方法中調用全局變量,需要global
 ? ?global a
 ? ?# 進行try-except
 ? ?try:
 ? ? ? ?print(f'開始嘗試!{a}')
 ? ? ? ?a+=1
 ? ? ? ?e1()
 ? ?except Exception as e:
 ? ? ? ?print(e)
 ? ? ? ?# 當重試完成后還未成功,則返回超時
 ? ? ? ?raise TimeoutError

以上代碼表示,我們只重試3次,如果還未成功,則返回超時異常。

代碼執行結果:

2.4、模擬最大重試時間

除了可以使用重試次數限制外,當我們對時間要求比較明確的時候,我們就可以使用stop_max_delay參數來指定最大重試時間。這個參數的單位是ms。

# 全局計數器
a=1
@retry(stop_max_delay=2000)
def demo1(n):
 ? ?# 方法中調用全局變量,需要global
 ? ?global a
 ? ?# 進行try-except
 ? ?try:
 ? ? ? ?print(f'開始嘗試!{a}')
 ? ? ? ?a+=1
 ? ? ? ?e1()
 ? ?except Exception as e:
 ? ? ? ?print(e)
 ? ? ? ?# 當重試完成后還未成功,則返回超時
 ? ? ? ?raise TimeoutError

如上代碼表示,當重試時間超過2s就會拋出超時異常。因為在e1方法中,每次調用都會休眠1s,所以對于限制兩秒,我們只能在2s內重試2次。

代碼執行結果:

2.5、模擬重試間隔時間

當我們不希望重試間隔時間太長的時候,我們可以使用參數wait_fixed指定重試的間隔時間。

# 全局計數器
a=1
@retry(stop_max_delay=6000,wait_fixed=1000)
def demo1(n):
 ? ?# 方法中調用全局變量,需要global
 ? ?global a
 ? ?# 進行try-except
 ? ?try:
 ? ? ? ?print(f'開始嘗試!{a}')
 ? ? ? ?a+=1
 ? ? ? ?e1()
 ? ?except Exception as e:
 ? ? ? ?print(e)
 ? ? ? ?# 當重試完成后還未成功,則返回超時
 ? ? ? ?raise TimeoutError

如上代碼表示最大重試時間6秒,重試間隔1秒,但是e1方法中還休眠了1秒,所以在6秒內,我們理論上只能重試4次(不是3次)。

代碼運行結果:

在此基礎上,retrying還為我們提供了隨機的重試間隔時間參數。

  • wait_random_min,重試間隔最小時間
  • wait_random_max,重試間隔最大時間

一般,這兩個參數都是成對出現,用于限制重試間隔時間的范圍。

2.6、指定重試調用的方法

retrying允許我們在重試的同時去調用一個方法。使用參數stop_func來指定這個方法名。

# attempts, delay這兩個參數是必填的
def stop_f(attempts, delay):
 ? ?print('發生異常了,正在進行重試!')
# 全局計數器
a=1
@retry(stop_func=stop_f,stop_max_delay=3)
def demo1(n):
 ? ?# 方法中調用全局變量,需要global
 ? ?global a
 ? ?# 進行try-except
 ? ?try:
 ? ? ? ?print(f'開始嘗試!{a}')
 ? ? ? ?a+=1
 ? ? ? ?e1()
 ? ?except Exception as e:
 ? ? ? ?print(e)
 ? ? ? ?# 當重試完成后還未成功,則返回超時
 ? ? ? ?raise TimeoutError

代碼運行結果:

但是stop_func存在一個問題就是和stop_max_delay、stop_max_attempt_number結合使用的時候,后面兩者會失效。

2.7、指定重試的異常類型

當我們需要針對特定的異常才進行重試時,就需要用到這個參數:retry_on_exception

2.8、指定重試的特定條件

當達到某個條件才會進行重試,需要使用參數:retry_on_result

原文鏈接:https://juejin.cn/post/7108202816665026573

欄目分類
最近更新