由於錯誤也是一個類,捕獲一個錯誤就是捕獲到該類的一個實例
所以,錯誤並非憑空產生的,而是有意建立並拋出的
Python的內置函數會拋出不少類型的錯誤,自定義函數也可拋出錯誤函數
自定義錯誤
若是要拋出錯誤,首先根據須要,能夠定義一個錯誤類,選擇好繼承關係,而後,用raise語句拋出一個錯誤的實例
必要時可自定義錯誤類型,但儘可能使用Python內置的錯誤類型spa
class FooError(ValueError): #繼承Python內置錯誤類型ValueError pass def foo(s): n = int(s) if n==0: raise FooError('invalid value: %s' % s) return 10 / n foo('0') #輸出: Traceback (most recent call last): File "err_throw.py", line 11, in <module> foo('0') File "err_throw.py", line 8, in foo raise FooError('invalid value: %s' % s) __main__.FooError: invalid value: 0
連續拋錯誤
捕獲錯誤目的只是記錄一下,便於後續追蹤,當前函數不知道應該怎麼處理該錯誤時,就要繼續往上拋,讓頂層調用者去處理該錯誤
若頂層調用者還沒法知道如何處理時,就繼續向上拋,直到錯誤獲得正確解決,不然程序會停止code
def foo(s): n = int(s) if n==0: raise ValueError('invalid value: %s' % s) return 10 / n def bar(): try: foo('0') except ValueError as e: print('ValueError!') raise #在bar()函數中已經捕獲了錯誤,但打印一個ValueError!後,又把錯誤經過raise語句拋出去了 bar()
關於raiseblog
raise語句若是不帶參數,就會把當前錯誤原樣拋出繼承
try: 10 / 0 except ZeroDivisionError: raise
在except中raise一個Error,還能夠把一種類型的錯誤轉化成另外一種類型
只要是合理的轉換邏輯就能夠,可是,決不該該把一個IOError轉換成絕不相干的ValueErrorinput
try: 10 / 0 except ZeroDivisionError: raise ValueError('input error!')