retrying是一個python的重試包芝硬,可以用來自動重試一些可能運行失敗的程序段蚜点,retrying提供一個裝飾器函數(shù)retry,被裝飾的函數(shù)就會在運行失敗的情況下重新執(zhí)行拌阴,默認(rèn)只要一直報錯就會不斷重試绍绘。
安裝
- 簡單的安裝retrying:
pip install retrying
參數(shù):
stop_max_attempt_number:在停止之前嘗試的最大次數(shù),最后一次如果還是有異常則會拋出異常迟赃,停止運行陪拘,默認(rèn)為5次
stop_max_delay:從被裝飾的函數(shù)開始執(zhí)行的時間點開始到函數(shù)成功運行結(jié)束或失敗報錯中止的時間點。單位:毫秒
wait_random_min:在兩次調(diào)用方法停留時長纤壁,停留最短時間左刽,默認(rèn)為0,單位毫秒
wait_random_max:在兩次調(diào)用方法停留時長,停留最長時間酌媒,默認(rèn)為1000毫秒
wait_fixed:設(shè)置在兩次retrying之間的停留時間
retry_on_exception:指定一個函數(shù)欠痴,如果此函數(shù)返回指定異常,則會重試秒咨,如果不是指定的異常則會退出
例:* retry_on_exception(retry_if_io_error)retry_on_result:指定一個函數(shù)喇辽,如果指定的函數(shù)返回True,則重試拭荤,否則拋出異常退出
功能:
一般裝飾器api
特定的停止條件(限制嘗試次數(shù))
特定的等待條件(每次嘗試之間的指數(shù)增長的時間等待)
自定義的異常進行嘗試
自定義的異常進行嘗試返回結(jié)果
最簡單的一個使用方法是無論有任何異常出現(xiàn)茵臭,都會一直重新調(diào)用一個函數(shù)、方法舅世,直到返回一個值
import random
from retrying import retry
@retry
def do_something_unreliable():
if random.randint(0, 10) > 1:
print "just have a test"
raise IOError("Broken sauce, everything is hosed!!!111one")
else:
return "Awesome sauce!"
print do_something_unreliable()
運行該段代碼旦委,你會發(fā)現(xiàn)每次隨機打印的“just have a test”這句話次數(shù)不一致
例子
正如你上邊看到的例子,默認(rèn)的行為會一直重試雏亚,沒有時間等待
@retry
def never_give_up_never_surrender():
print "Retry forever ignoring Exceptions, don't wait between retries"
騷年缨硝,不要太固執(zhí),加點限制罢低,放棄之前查辩,嘗試幾次(代碼嘗試幾次后停止)
@retry(stop_max_attempt_number=7)
def stop_after_7_attempts():
print "Stopping after 7 attempts"
我們沒有太多的時間,所以在每個嘗試需要加個時間限制(多少s后停止嘗試)
@retry(stop_max_delay=10000)
def stop_after_10_s():
print "Stopping after 10 seconds"
大多數(shù)事情并不是需要盡可能快的執(zhí)行网持,所以加一些時間等待(每個嘗試間加固定時間等待)
@retry(wait_fixed=2000)
def wait_2_s():
print "Wait 2 second between retries"
一些最好是隨機的時間等待(每個嘗試隨機時間等待)
@retry(wait_random_min=1000, wait_random_max=2000)
def wait_random_1_to_2_s():
print "Randomly wait 1 to 2 seconds between retries"
再一次宜岛,在重新嘗試分布式服務(wù)和其他遠程端點時,很難擊敗指數(shù)級回退(不會翻譯功舀,大概就是每次嘗試的等待時間以指數(shù)形式增長)
@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
def wait_exponential_1000():
print "Wait 2^x * 1000 milliseconds between each retry, up to 10 seconds, then 10 seconds afterwards"
我們有一些處理重新嘗試的選項萍倡,它們會引起特定的或一般的異常,就像這里的情況一樣(根據(jù)異常重試)
def retry_if_io_error(exception):
"""Return True if we should retry (in this case when it's an IOError), False otherwise"""
return isinstance(exception, IOError)
@retry(retry_on_exception=retry_if_io_error)
def might_io_error():
print "Retry forever with no wait if an IOError occurs, raise any other errors"
@retry(retry_on_exception=retry_if_io_error, wrap_exception=True)
def only_raise_retry_error_when_not_io_error():
print "Retry forever with no wait if an IOError occurs, raise any other errors
我們也可以使用函數(shù)的結(jié)果來改變重新嘗試的行為
def retry_if_result_none(result):
"""Return True if we should retry (in this case when result is None), False otherwise"""
return result is None
@retry(retry_on_result=retry_if_result_none)
def might_return_none():
print "Retry forever ignoring Exceptions with no wait if return value is None"
任何停止辟汰、等待等的組合也會被支持列敲,使你可以自由地混合和匹配阱佛。騷男,嘗試起來吧戴而!