<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      翻譯:《實(shí)用的Python編程》03_03_Error_checking

      目錄 | 上一節(jié) (3.2 深入函數(shù)) | 下一節(jié) (3.4 模塊)

      3.3 錯(cuò)誤檢查

      雖然前面已經(jīng)介紹了異常,但本節(jié)補(bǔ)充一些有關(guān)錯(cuò)誤檢查和異常處理的其它細(xì)節(jié)。

      程序是如何運(yùn)行失敗的

      Python 不對(duì)函數(shù)參數(shù)類(lèi)型或值進(jìn)行檢查或者校驗(yàn)。函數(shù)可以處理與函數(shù)內(nèi)部語(yǔ)句兼容的任何數(shù)據(jù)。

      def add(x, y):
          return x + y
      
      add(3, 4)               # 7
      add('Hello', 'World')   # 'HelloWorld'
      add('3', '4')           # '34'
      

      如果函數(shù)中有錯(cuò)誤,它們將(作為異常)在運(yùn)行時(shí)出現(xiàn)。

      def add(x, y):
          return x + y
      
      >>> add(3, '4')
      Traceback (most recent call last):
      ...
      TypeError: unsupported operand type(s) for +:
      'int' and 'str'
      >>>
      

      為了驗(yàn)證代碼,強(qiáng)烈建議進(jìn)行測(cè)試(稍后介紹)。

      異常

      異常用于發(fā)出錯(cuò)誤信號(hào)。

      要自己觸發(fā)異常,請(qǐng)使用 raise 語(yǔ)句:

      if name not in authorized:
          raise RuntimeError(f'{name} not authorized')
      

      要捕獲異常,請(qǐng)使用 try-except 語(yǔ)句:

      try:
          authenticate(username)
      except RuntimeError as e:
          print(e)
      

      異常處理

      異常傳遞到第一個(gè)匹配的 except

      def grok():
          ...
          raise RuntimeError('Whoa!')   # Exception raised here
      
      def spam():
          grok()                        # Call that will raise exception
      
      def bar():
          try:
             spam()
          except RuntimeError as e:     # Exception caught here
              ...
      
      def foo():
          try:
               bar()
          except RuntimeError as e:     # Exception does NOT arrive here
              ...
      
      foo()
      

      要處理異常,請(qǐng)將語(yǔ)句放到 except 塊里面。 except 塊里面可以添加要處理該錯(cuò)誤的任何語(yǔ)句。

      def grok(): ...
          raise RuntimeError('Whoa!')
      
      def bar():
          try:
            grok()
          except RuntimeError as e:   # Exception caught here
              statements              # Use this statements
              statements
              ...
      
      bar()
      

      異常處理之后,從 try-except 之后的第一個(gè)語(yǔ)句繼續(xù)執(zhí)行。

      def grok(): ...
          raise RuntimeError('Whoa!')
      
      def bar():
          try:
            grok()
          except RuntimeError as e:   # Exception caught here
              statements
              statements
              ...
          statements                  # Resumes execution here
          statements                  # And continues here
          ...
      
      bar()
      

      內(nèi)置異常

      有非常多的內(nèi)建異常。通常,異常名稱(chēng)表明出了什么問(wèn)題(例如,因?yàn)樘峁╁e(cuò)誤的值而觸發(fā) ValueError)。下述列表不是一份詳盡的清單,請(qǐng)?jiān)L問(wèn) 文檔 以獲取更多信息。

      ArithmeticError
      AssertionError
      EnvironmentError
      EOFError
      ImportError
      IndexError
      KeyboardInterrupt
      KeyError
      MemoryError
      NameError
      ReferenceError
      RuntimeError
      SyntaxError
      SystemError
      TypeError
      ValueError
      

      異常值

      異常具有一個(gè)關(guān)聯(lián)值。它包含有關(guān)錯(cuò)誤的更明確的信息。

      raise RuntimeError('Invalid user name')
      

      這個(gè)值是異常實(shí)例的一部分,它被放置在提供給 except 的變量中。

      try:
          ...
      except RuntimeError as e:   # `e` holds the exception raised
          ...
      

      e 是異常類(lèi)型的一個(gè)實(shí)例。但是,當(dāng)打印的時(shí)候,它通常看起來(lái)像一個(gè)字符串。

      except RuntimeError as e:
          print('Failed : Reason', e)
      

      捕獲多個(gè)異常

      可以使用多個(gè) except 塊捕獲不同類(lèi)型的異常:

      try:
        ...
      except LookupError as e:
        ...
      except RuntimeError as e:
        ...
      except IOError as e:
        ...
      except KeyboardInterrupt as e:
        ...
      

      或者,如果處理不同異常的語(yǔ)句是相同的,則可以對(duì)它們進(jìn)行分組:

      try:
        ...
      except (IOError,LookupError,RuntimeError) as e:
        ...
      

      捕獲所有的異常

      要捕獲所有的異常,請(qǐng)使用 Exception 。如下所示:

      try:
          ...
      except Exception:       # DANGER. See below
          print('An error occurred')
      

      通常,像這樣編寫(xiě)代碼是個(gè)壞主意,因?yàn)檫@說(shuō)明不知道程序?yàn)槭裁磿?huì)失敗。

      捕獲異常的錯(cuò)誤方式

      這里是一個(gè)使用異常的錯(cuò)誤方式。

      try:
          go_do_something()
      except Exception:
          print('Computer says no')
      

      這將捕獲所有可能的錯(cuò)誤,并且,當(dāng)代碼因?yàn)槟承└緵](méi)想到的原因(如卸載 Python 模塊等)運(yùn)行失敗時(shí),可能無(wú)法進(jìn)行調(diào)試。

      更好的方式

      如果想要捕獲所有的錯(cuò)誤,這有一個(gè)更明智的方法。

      try:
          go_do_something()
      except Exception as e:
          print('Computer says no. Reason :', e)
      

      它報(bào)告了失敗的明確原因。當(dāng)編寫(xiě)捕獲所有可能異常的代碼時(shí),擁有查看/報(bào)告錯(cuò)誤的機(jī)制幾乎總是一個(gè)好主意。

      不過(guò),通常來(lái)說(shuō),最好在合理的范圍內(nèi)盡量窄地捕獲異常。僅捕獲能處理的異常。讓其它錯(cuò)誤通過(guò)——也許其它代碼可以處理。

      重新觸發(fā)異常

      使用 raise 傳遞捕獲的錯(cuò)誤。

      try:
          go_do_something()
      except Exception as e:
          print('Computer says no. Reason :', e)
          raise
      

      這允許你采取措施(例如:記錄日志)并將錯(cuò)誤傳遞給調(diào)用者。

      異常的最佳實(shí)踐

      不要捕獲異常,而是失敗發(fā)生時(shí)“停止運(yùn)行,發(fā)出預(yù)警”(Fail fast and loud)。如果重要的話(huà),別人會(huì)處理的。只有你是那個(gè)人的時(shí)候才捕獲異常。即,只捕獲可以恢復(fù)并正常運(yùn)行的錯(cuò)誤。

      finally 語(yǔ)句

      finally 語(yǔ)句指定無(wú)論是否發(fā)生異常都必須運(yùn)行的代碼。

      lock = Lock()
      ...
      lock.acquire()
      try:
          ...
      finally:
          lock.release()  # this will ALWAYS be executed. With and without exception.
      

      通常使用 finally 語(yǔ)句安全地管理資源(尤其是鎖,文件等)。

      with 語(yǔ)句

      在現(xiàn)代代碼中,try-finally 語(yǔ)句通常被 with 語(yǔ)句取代。

      lock = Lock()
      with lock:
          # lock acquired
          ...
      # lock released
      

      一個(gè)更熟悉的例子:

      with open(filename) as f:
          # Use the file
          ...
      # File closed
      

      with 語(yǔ)句定義資源的使用上下文。當(dāng)執(zhí)行離開(kāi)上下文時(shí),資源被釋放。with 語(yǔ)句僅適用于經(jīng)過(guò)專(zhuān)門(mén)編程以支持它的某些對(duì)象。

      練習(xí)

      練習(xí) 3.8:觸發(fā)異常

      在上一節(jié)中編寫(xiě)的 parse_csv() 函數(shù)允許選擇用戶(hù)指定的列,但是只有輸入數(shù)據(jù)文件具有列標(biāo)題時(shí)才會(huì)生效。

      請(qǐng)修改代碼,以便在同時(shí)傳遞 selecthas_headers=False 參數(shù)時(shí)觸發(fā)異常。例如:

      >>> parse_csv('Data/prices.csv', select=['name','price'], has_headers=False)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "fileparse.py", line 9, in parse_csv
          raise RuntimeError("select argument requires column headers")
      RuntimeError: select argument requires column headers
      >>>
      

      添加此檢查后,你可能會(huì)問(wèn)是否應(yīng)該在函數(shù)中執(zhí)行其它類(lèi)型的完整性檢查。例如,檢查文件名是字符串,列表還是其它類(lèi)型?

      一般來(lái)說(shuō),最好是跳過(guò)此類(lèi)測(cè)試,輸入錯(cuò)誤的時(shí)候讓程序運(yùn)行失敗?;厮菪畔?huì)指出問(wèn)題的根源,并且?guī)椭{(diào)試。

      添加上述檢查的主要原因是為了避免在無(wú)意義的模式下運(yùn)行代碼(例如,使用要求列標(biāo)題的特性,但是同時(shí)指定沒(méi)有標(biāo)題)。

      這表明調(diào)用代碼部分出現(xiàn)一個(gè)編程錯(cuò)誤。檢查“不應(yīng)發(fā)生”的情況通常是個(gè)好主意。

      練習(xí) 3.9:捕獲異常

      你編寫(xiě)的 parse_csv() 函數(shù)用于處理文件的全部?jī)?nèi)容。但是,在現(xiàn)實(shí)世界中,輸入文件可能包含損壞的數(shù)據(jù),丟失的數(shù)據(jù)或者臟數(shù)據(jù)。嘗試下面這個(gè)實(shí)驗(yàn):

      >>> portfolio = parse_csv('Data/missing.csv', types=[str, int, float])
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "fileparse.py", line 36, in parse_csv
          row = [func(val) for func, val in zip(types, row)]
      ValueError: invalid literal for int() with base 10: ''
      >>>
      

      請(qǐng)修改 parse_csv() 函數(shù)以便捕獲所有在記錄創(chuàng)建期間生成的 ValueError 異常,并為無(wú)法轉(zhuǎn)換的行打印警告消息。

      錯(cuò)誤消息應(yīng)該包括行號(hào)以及有關(guān)失敗原因的信息。要測(cè)試函數(shù),嘗試讀取上面的 Data/missing.csv 文件,例如:

      >>> portfolio = parse_csv('Data/missing.csv', types=[str, int, float])
      Row 4: Couldn't convert ['MSFT', '', '51.23']
      Row 4: Reason invalid literal for int() with base 10: ''
      Row 7: Couldn't convert ['IBM', '', '70.44']
      Row 7: Reason invalid literal for int() with base 10: ''
      >>>
      >>> portfolio
      [{'price': 32.2, 'name': 'AA', 'shares': 100}, {'price': 91.1, 'name': 'IBM', 'shares': 50}, {'price': 83.44, 'name': 'CAT', 'shares': 150}, {'price': 40.37, 'name': 'GE', 'shares': 95}, {'price': 65.1, 'name': 'MSFT', 'shares': 50}]
      >>>
      

      練習(xí) 3.10:隱藏錯(cuò)誤

      請(qǐng)修改 parse_csv()函數(shù),以便用戶(hù)明確需要時(shí)可以隱藏解析的錯(cuò)誤消息,例如:

      >>> portfolio = parse_csv('Data/missing.csv', types=[str,int,float], silence_errors=True)
      >>> portfolio
      [{'price': 32.2, 'name': 'AA', 'shares': 100}, {'price': 91.1, 'name': 'IBM', 'shares': 50}, {'price': 83.44, 'name': 'CAT', 'shares': 150}, {'price': 40.37, 'name': 'GE', 'shares': 95}, {'price': 65.1, 'name': 'MSFT', 'shares': 50}]
      >>>
      

      在大部分的程序中,錯(cuò)誤處理是最難做好的事情之一。一般來(lái)說(shuō),不應(yīng)該默默地忽略錯(cuò)誤。相反,最好是報(bào)告問(wèn)題,并且讓用戶(hù)選擇是否隱藏錯(cuò)誤信息(如果它們選擇這樣做)。

      目錄 | 上一節(jié) (3.2 深入函數(shù)) | 下一節(jié) (3.4 模塊)

      注:完整翻譯見(jiàn) https://github.com/codists/practical-python-zh

      posted @ 2021-03-02 22:35  codists  閱讀(345)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲国产在一区二区三区| 婷婷久久综合九色综合88| 国产欧美在线一区二区三| 国产精品人妻一区二区高 | 丁香五月网久久综合| 亚洲精品日本久久久中文字幕| 国产老熟女无套内射不卡| 国产一区二区视频在线看| 国产91色在线精品三级| 免费无码VA一区二区三区| 国产精品无码一区二区在线| 亚洲午夜理论无码电影| 四虎永久精品在线视频| 亚洲国产精品一二三区| 久久久无码精品国产一区| 老太脱裤子让老头玩xxxxx| 国内精品视这里只有精品| 猫咪AV成人永久网站在线观看| 国产精品自产在线观看一| 国产精品无码mv在线观看| 阿尔山市| 99在线 | 亚洲| 中国老太婆video| 产综合无码一区| 国产一区二区三区禁18| 久久这里只精品热免费99| 国产福利在线观看免费第一福利 | 性中国videossexo另类| 国产jjizz女人多水喷水| 无码福利写真片视频在线播放| 波多结野衣一区二区三区| 777奇米四色成人影视色区| 四虎永久免费高清视频| 重口SM一区二区三区视频| 被灌满精子的少妇视频| 国产高清乱码又大又圆| 久久久久青草线综合超碰| 亚洲天堂av日韩精品| 少妇办公室好紧好爽再浪一点| 好男人日本社区www| 中文字幕v亚洲日本在线电影|