天天看點

【python】錯誤 調試 測試try except finally raise

錯誤:有的錯誤是程式編寫有問題造成的,比如本來應該輸出整數結果輸出了字元串,這種錯誤我們通常稱之為bug,bug是必須修複的;有的錯誤是使用者輸入造成的,比如讓使用者輸入email位址,結果得到一個空字元串,這種錯誤可以通過檢查使用者輸入來做相應的處理。還有一類錯誤是完全無法在程式運作過程中預測的,比如寫入檔案的時候,磁盤滿了,寫不進去了,或者從網絡抓取資料,網絡突然斷掉了。這類錯誤也稱為異常,在程式中通常是必須處理的,否則,程式會因為各種問題終止并退出。

調試:跟蹤程式的執行,檢視變量的值是否正确,這個過程稱為調試。Python的pdb可以讓我們以單步方式執行代碼

測試:編寫測試也很重要。有了良好的測試,就可以在程式修改後反複運作,確定程式輸出符合我們編寫的測試。

錯誤處理:在程式運作的過程中,如果發生了錯誤,可以事先約定傳回一個錯誤代碼,這樣,就可以知道是否有錯,以及出錯的原因。在作業系統提供的調用中,傳回錯誤碼非常常見。比如打開檔案的函數open(),成功時傳回檔案描述符(就是一個整數),出錯時傳回-1。用錯誤碼來表示是否出錯十分不便,因為函數本身應該傳回的正常結果和錯誤碼混在一起,造成調用者必須用大量的代碼來判斷是否出錯。

進階語言通常都内置了一套

try...except...finally...

的錯誤處理機制,Python也不例外。

try:
   print('try:')
   r=10/0
   print(r)
except(ZeroDivisionError,IndexError,ValueError):
   print('excep:',TypeError,IndexError,ValueError)
finally:
   print('finally..')
print('end')
 
#tracking error
def foo(s):
   return 10 / int(s)
 
def bar(s):
   return foo(s) * 2
 
def main():
   bar('2')
 
main()
 
           

Python的錯誤其實也是class,所有的錯誤類型都繼承自

BaseException

,是以在使用

except

時需要注意的是,它不但捕獲該類型的錯誤,還把其子類也“一網打盡”。如果錯誤沒有被捕獲,它就會一直往上抛,最後被Python解釋器捕獲,列印一個錯誤資訊,然後程式退出。Python内置的

logging

子產品可以非常容易地記錄錯誤資訊。

因為錯誤是class,捕獲一個錯誤就是捕獲到該class的一個執行個體。是以,錯誤并不是憑空産生的,而是有意建立并抛出的。Python的内置函數會抛出很多類型的錯誤,我們自己編寫的函數也可以抛出錯誤。

如果要抛出錯誤,首先根據需要,可以定義一個錯誤的class,選擇好繼承關系,然後,用

raise

語句抛出一個錯誤的執行個體:

# err.py
class FooError(StandardError):
    pass
 
def foo(s):
    n = int(s)
    if n==0:
        raise FooError('invalid value: %s' % s)
    return 10 / n
           

隻有在必要的時候才定義我們自己的錯誤類型。如果可以選擇Python已有的内置的錯誤類型(比如ValueError,TypeError),盡量使用Python内置的錯誤類型。

下面為錯誤類型和繼承關系:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StandardError
      |    +-- BufferError
      |    +-- ArithmeticError
      |    |    +-- FloatingPointError
      |    |    +-- OverflowError
      |    |    +-- ZeroDivisionError
      |    +-- AssertionError
      |    +-- AttributeError
      |    +-- EnvironmentError
      |    |    +-- IOError
      |    |    +-- OSError
      |    |         +-- WindowsError (Windows)
      |    |         +-- VMSError (VMS)
      |    +-- EOFError
      |    +-- ImportError
      |    +-- LookupError
      |    |    +-- IndexError
      |    |    +-- KeyError
      |    +-- MemoryError
      |    +-- NameError
      |    |    +-- UnboundLocalError
      |    +-- ReferenceError
      |    +-- RuntimeError
      |    |    +-- NotImplementedError
      |    +-- SyntaxError
      |    |    +-- IndentationError
      |    |         +-- TabError
      |    +-- SystemError
      |    +-- TypeError
      |    +-- ValueError
      |         +-- UnicodeError
      |              +-- UnicodeDecodeError
      |              +-- UnicodeEncodeError
      |              +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
	   +-- ImportWarning
	   +-- UnicodeWarning
	   +-- BytesWarning