retrying是一個很好用的關於重試的Python包,能夠用來自動重試一些可能會運行失敗的程序段。python
咱們在寫一些程序的時候,會去調用一些外部資源、組件,這些外部程序對咱們來講是不可控的,因此它們不可用、運行失敗都是正常的事情,尤爲是在網絡上多個服務交互的時候,在寫程序的時候必定要考慮調用外部程序會失敗的狀況。git
retrying就是一個能夠用來應對上述問題的工具,能夠在PyPi上得到。
retrying提供一個裝飾器函數retry
,被裝飾的函數就會在運行失敗的條件下從新執行,默認只要一直報錯就會不斷重試,看一下下面的例子:github
import random from retrying import retry @retry def have_a_try(): if random.randint(0, 10) != 5: raise Exception('It's not 5!') print 'It's 5!'
若是咱們運行have_a_try
函數,那麼直到random.randint
返回5
,它纔會執行結束,不然會一直從新執行。
retry還能夠接受一些參數,這個從源碼中Retrying類的初始化函數能夠看到可選的參數:算法
def __init__(self, stop=None, wait=None, stop_max_attempt_number=None, stop_max_delay=None, wait_fixed=None, wait_random_min=None, wait_random_max=None, wait_incrementing_start=None, wait_incrementing_increment=None, wait_exponential_multiplier=None, wait_exponential_max=None, retry_on_exception=None, retry_on_result=None, wrap_exception=False, stop_func=None, wait_func=None, wait_jitter_max=None)
stop_max_attempt_number
:用來設定最大的嘗試次數,超過該次數就中止重試網絡
stop_max_delay
:好比設置成10000,那麼從被裝飾的函數開始執行的時間點開始,到函數成功運行結束或者失敗報錯停止的時間點,只要這段時間超過10秒,函數就不會再執行了dom
wait_fixed
:設置在兩次retrying之間的停留時間函數
wait_random_min
和wait_random_max
:用隨機的方式產生兩次retrying之間的停留時間工具
wait_exponential_multiplier
和wait_exponential_max
:以指數的形式產生兩次retrying之間的停留時間,產生的值爲2^previous_attempt_number * wait_exponential_multiplier,previous_attempt_number是前面已經retry的次數,若是產生的這個值超過了wait_exponential_max的大小,那麼以後兩個retrying之間的停留值都爲wait_exponential_max。這個設計迎合了exponential backoff算法,能夠減輕阻塞的狀況。設計
咱們能夠指定要在出現哪些異常的時候再去retry,這個要用retry_on_exception
傳入一個函數對象:code
def retry_if_io_error(exception): return isinstance(exception, IOError) @retry(retry_on_exception=retry_if_io_error) def read_a_file(): with open("file", "r") as f: return f.read()
在執行read_a_file
函數的過程當中,若是報出異常,那麼這個異常會以形參exception
傳入retry_if_io_error
函數中,若是exception
是IOError
那麼就進行retry,若是不是就中止運行並拋出異常。
咱們還能夠指定要在獲得哪些結果的時候去retry,這個要用retry_on_result
傳入一個函數對象:
def retry_if_result_none(result): return result is None @retry(retry_on_result=retry_if_result_none) def get_result(): return None
在執行get_result成功後,會將函數的返回值經過形參result
的形式傳入retry_if_result_none
函數中,若是返回值是None
那麼就進行retry,不然就結束並返回函數值。