Python之retrying

retrying是一個很好用的關於重試的Python包,能夠用來自動重試一些可能會運行失敗的程序段。python

爲何選擇retrying

咱們在寫一些程序的時候,會去調用一些外部資源、組件,這些外部程序對咱們來講是不可控的,因此它們不可用、運行失敗都是正常的事情,尤爲是在網絡上多個服務交互的時候,在寫程序的時候必定要考慮調用外部程序會失敗的狀況。git

retrying

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_minwait_random_max:用隨機的方式產生兩次retrying之間的停留時間工具

  • wait_exponential_multiplierwait_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函數中,若是exceptionIOError那麼就進行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,不然就結束並返回函數值。

參考資料

相關文章
相關標籤/搜索