Python中異常重試的解決方案詳解


  • https://www.jb51.net/article/112954.htm

    原先的流程:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def crawl_page(url):
      pass
      
    def log_error(url):
      pass
      
    url = ""
    try :
      crawl_page(url)
    except :
      log_error(url)

    改進后的流程:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    attempts = 0
    success = False
    while attempts < 3 and not success:
      try :
       crawl_page(url)
       success = True
      except :
       attempts + = 1
       if attempts = = 3 :
        break

     

    最近發現的新的解決方案:retrying

    retrying是一個 Python的重試包,可以用來自動重試一些可能運行失敗的程序段。retrying提供一個裝飾器函數retry,被裝飾的函數就會在運行失敗的條件下重新執行,默認只要一直報錯就會不斷重試。

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import random
    from retrying import retry
      
    @retry
    def do_something_unreliable():
      if random.randint( 0 , 10 ) > 1 :
       raise IOError( "Broken sauce, everything is hosed!!!111one" )
      else :
       return "Awesome sauce!"
      
    print do_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_multiplierprevious_attempt_number是前面已經retry的次數,如果產生的這個值超過了wait_exponential_max的大小,那么之后兩個retrying之間的停留值都為wait_exponential_max。這個設計迎合了exponential backoff算法,可以減輕阻塞的情況。
    • 我們可以指定要在出現哪些異常的時候再去retry,這個要用retry_on_exception傳入一個函數對象:
    ?
    1
    2
    3
    4
    5
    6
    7
    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傳入一個函數對象:

    ?
    1
    2
    3
    4
    5
    6
    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,否則就結束並返回函數值。

    總結

    以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM