<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          90%老手的都不知道,Python異常還能寫得如此優(yōu)雅!

          共 5632字,需瀏覽 12分鐘

           ·

          2022-03-04 14:10


          在寫程序時,我們會經(jīng)常碰到程序出現(xiàn)異常,這時候我們就不得不處理這些異常,以保證程序的健壯性。

          處理異常的版本有以下幾種,你通常的做法是哪種?


          不負責任版本

          這種情況下,不作任何處理,任由程序報錯,從而導致程序中斷。

          針對簡單的程序,這樣做沒什么問題,大不了我遇到問題之后把問題解決,然后重新運行。但是如果是復雜的系統(tǒng)就會很麻煩了,可能你一個異常阻塞了系統(tǒng)的運行,帶來災難性的后果。

          簡單處理版本

          簡單處理版本,就是加上異常捕獲,在發(fā)生異常時記錄日志,時候可以通過日志來定位異常。

          def do_something():
              pass
          def log_error(xxx):
              pass

          try:
             do_something()
          except:
              log_error(xxxx)

          改進處理版本

          對于簡單處理版本做了改進,增加重試次數(shù)。這個在爬蟲程序中比較常見,第一次請求超時,可能過一會再請求就成功了,所以重試幾次可能會消除異常。

          attempts = 0
          success = False
          while attempts < 3 and not success:
              try:
                  do_something()
                  success = True
              except:
                  attempts += 1
                  if attempts == 3:
                      break

          但是這樣做仍然不夠優(yōu)雅,你可能要在很多地方去寫這種重試的硬編碼,程序看起來亂糟糟的。


          今天就給大家介紹一個第三方模塊 —— retrying。它是對程序中異常重試的一種優(yōu)雅的解決方案。

          安裝與使用

          安裝

          安裝命令還是那么平淡無奇:

          pip install retrying

          使用

          下面給大家介紹一下這個裝飾函數(shù)有哪些可以使用的參數(shù)。

          生命不息,奮斗不止

          retrying 提供一個裝飾器函數(shù) retry,被裝飾的函數(shù)會在運行失敗的情況下重新執(zhí)行,默認一直報錯就一直重試。

          import random
          from retrying import retry

          @retry
          def do_something_unreliable():
              if random.randint(010) > 1:
                  print("just have a test")
                  raise IOError("raise exception!")
              else:
                  return "good job!"

          print(do_something_unreliable())

          運行這個程序,大家可以看到每次打印“just have a test”這句話的次數(shù)都不一樣。這是由于我們程序中只要隨機整數(shù)大于1就會打印并且拋出異常。但是由于我們有裝飾器函數(shù) retry,所以在發(fā)生異常就會重新再次執(zhí)行方法,直到隨機整數(shù)大于1,就會打印“good job!”。

          做人不能太固執(zhí)

          這種無休止地重試,簡直是浪費生命,浪費資源。我們要建設綠色家園,所以不妨加點限制:

          # 最大重試次數(shù)
          @retry(stop_max_attempt_number=5)
          def do_something_limited():
              print("do something several times")
              raise Exception("raise exception")

          do_something_limited()

          珍惜有限的時間

          一寸光陰一寸金,寸金難買寸光陰。我們要珍惜有限的時間,所以不妨給我們的重試加個時間限制:

          # 限制最長重試時間(從執(zhí)行方法開始計算)
          @retry(stop_max_delay=5000)
          def do_something_in_time():
              print("do something in time")
              raise Exception("raise exception")

          do_something_in_time()

          駐足欣賞路上風景

          人生匆匆數(shù)十載,不要一路狂奔而忘記欣賞路邊的美景,有時候我們需要花點時間來欣賞一路的美景:

          # 設置固定重試時間
          @retry(wait_fixed=2000)
          def wait_fixed_time():
              print("wait")
              raise Exception("raise exception")

          wait_fixed_time()

          給失敗設個限

          雖說我們需要屢敗屢戰(zhàn)的韌性,但是失敗也要有個限度,不能在失敗中度過一生:

          # 設置重試時間的隨機范圍
          @retry(wait_random_min=1000,wait_random_max=2000)
          def wait_random_time():
              print("wait")
              raise Exception("raise exception")

          wait_random_time()

          有些人值得等待

          茫茫人海中,我就是要等到那個對的人:

          # 根據(jù)異常重試
          def retry_if_io_error(exception):
              return isinstance(exception, IOError)

          # 設置特定異常類型重試
          @retry(retry_on_exception=retry_if_io_error)
          def retry_special_error():
              print("retry io error")
              raise IOError("raise exception")

          retry_special_error()

          我們自己定義一個函數(shù),判斷異常類型,然后將函數(shù)作為參數(shù)傳給裝飾函數(shù) retry ,如果異常類型符合,就會進行重試。

          有些結果是我們希望見到的

          人生并不是一帆風順,有些時候我們會遇到挫折,這些挫折也許在一開始就是我們想要的:

          # 通過返回值判斷是否重試
          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
              if result =="111":
                  return True


          @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")
              return "111"

          might_return_none()

          這里我們定義了一個判斷返回值的函數(shù),然后將這個函數(shù)作為參數(shù)傳給 retry 裝飾函數(shù)。當結果返回是“111”時,就會一直重試執(zhí)行 might_return_none 函數(shù)。

          生活豐富多彩,并不單調

          我們的生活是豐富多彩的,從來都沒有很單調。所以上面這些參數(shù),我們可以隨意組合使用,并不限定每次只能用一個。比如你可以限定遇到 IOError 時進行重試,并且重試次數(shù)最多5次。

          總結

          人生不可重來,但是Python可以重試!

          我已經(jīng)將retrying 這個裝飾函數(shù)的使用方法毫無保留地奉獻給各位看官了,趕快用起來吧!


          有興趣的同學可以火速加入我們的星球
          3周零基礎入門提供10節(jié)課程
          全年12節(jié)趣味實戰(zhàn)項目含源碼,
          每月獎勵優(yōu)秀的Top3同學送書
          專業(yè)的答疑群,大廠的老師保姆式的教學

          如果不滿意,三天內隨意退款!一年88,現(xiàn)在優(yōu)惠16元


          掃碼加入,3周零基礎入門




          推薦閱讀:

          入門: 最全的零基礎學Python的問題  | 零基礎學了8個月的Python  | 實戰(zhàn)項目 |學Python就是這條捷徑


          干貨:爬取豆瓣短評,電影《后來的我們》 | 38年NBA最佳球員分析 |   從萬眾期待到口碑撲街!唐探3令人失望  | 笑看新倚天屠龍記 | 燈謎答題王 |用Python做個海量小姐姐素描圖 |碟中諜這么火,我用機器學習做個迷你推薦系統(tǒng)電影


          趣味:彈球游戲  | 九宮格  | 漂亮的花 | 兩百行Python《天天酷跑》游戲!


          AI: 會做詩的機器人 | 給圖片上色 | 預測收入 | 碟中諜這么火,我用機器學習做個迷你推薦系統(tǒng)電影


          小工具: Pdf轉Word,輕松搞定表格和水?。?/a> | 一鍵把html網(wǎng)頁保存為pdf!|  再見PDF提取收費! | 用90行代碼打造最強PDF轉換器,word、PPT、excel、markdown、html一鍵轉換 | 制作一款釘釘?shù)蛢r機票提示器! |60行代碼做了一個語音壁紙切換器天天看小姐姐!


          年度爆款文案

          點閱讀原文,看200個Python案例!

          瀏覽 63
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲A片一区二区三区电影网 | 操屄一级片 | 亚洲黄色成人网站 | 精品第一| 原创黄瓜操逼爆浆 |