-
https://www.jb51.net/article/112954.htm
原先的流程:
1234567891011defcrawl_page(url):passdeflog_error(url):passurl=""try:crawl_page(url)except:log_error(url)改進后的流程:
12345678910attempts=0success=Falsewhileattempts <3andnotsuccess:try:crawl_page(url)success=Trueexcept:attempts+=1ifattempts==3:break最近發現的新的解決方案:retrying
retrying是一個 Python的重試包,可以用來自動重試一些可能運行失敗的程序段。
retrying提供一個裝飾器函數retry,被裝飾的函數就會在運行失敗的條件下重新執行,默認只要一直報錯就會不斷重試。1234567891011importrandomfromretryingimportretry@retrydefdo_something_unreliable():ifrandom.randint(0,10) >1:raiseIOError("Broken sauce, everything is hosed!!!111one")else:return"Awesome sauce!"printdo_something_unreliable()retry還可以接受一些參數,這個從源碼中Retrying類的初始化函數可以看到可選的參數:
stop_max_attempt_number:用來設定最大的嘗試次數,超過該次數就停止重試-
stop_max_delay:比如設置成10000,那么從被裝飾的函數開始執行的時間點開始,到函數成功運行結束或者失敗報錯中止的時間點,只要這段時間超過10秒,函數就不會再執行了 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傳入一個函數對象:
1234567defretry_if_io_error(exception):returnisinstance(exception, IOError)@retry(retry_on_exception=retry_if_io_error)defread_a_file():withopen("file","r") as f:returnf.read()在執行
read_a_file函數的過程中,如果報出異常,那么這個異常會以形參exception傳入retry_if_io_error函數中,如果exception是IOError那么就進行retry,如果不是就停止運行並拋出異常。我們還可以指定要在得到哪些結果的時候去
retry,這個要用retry_on_result傳入一個函數對象:123456defretry_if_result_none(result):returnresultisNone@retry(retry_on_result=retry_if_result_none)defget_result():returnNone在執行
get_result成功后,會將函數的返回值通過形參result的形式傳入retry_if_result_none函數中,如果返回值是None那么就進行retry,否則就結束並返回函數值。總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
