【python教程】4、定義、引發建立、捕獲異常
阿新 • • 發佈:2021-07-28
1、什麼是異常
python使用異常物件
來表示異常狀態,並在遇到錯誤時引發異常。異常物件未被處理或捕獲時,程式將終止並顯示一條錯誤訊息(traceback)。如下:
>>> 1/0
Traceback(most recent call last):
File"<stdin>", line 1, in?
ZeroDivisionError.integer division or modulo by zero
每個異常都是某個類(如ZeroDivisionError)的例項,我們可以以各種方式引發和捕獲這些例項,從而逮住錯誤並採取措施,而不是放任整個程式失敗。
2、引發和建立異常
raise語句引發異常:將一個類(必須是Exception的子類)或例項作為引數。
raise Exception # 將類作為引數時,將自動建立一個例項。這裡引發的是通用異常,沒有指出出現了什麼錯誤。
raise Exception('hyperdrive overload') # 添加了錯誤訊息hyperdrive overload
比較重要的一些內建的異常類:
Exception:幾乎所有的異常類都是從它派生而來的 AttributeError:引用屬性或給他賦值失敗時引發 OSError:作業系統不能執行指定的任務(如開啟檔案)時引發,有多個子類 indexError:使用序列中不存在的索引時引發,為LookupError的子類 KeyError:使用對映中不存在的鍵時引發,為LookupError的子類 NameError:找不到名稱(或變數)時引發 SyntaxError:程式碼不正確時引發 TypeError:將內建操作或函式用於型別不正確的物件時引發 ValueError:將內建操作或函式用於這樣的物件時引發:其型別正確但包含的值不合適 ZeroDivisionError:在除法或求模運算的第二個引數為0時引發
3、捕獲異常
異常有趣的地方是可對其進行處理,稱之為捕獲異常。常用:try/except語句。基本用法:
# 一:捕獲異常並對錯誤進行處理(列印友好的錯誤訊息) try: x = int(input('first number:')) y = int(input('second number:')) print(x / y) except ZeroDivisionError: print("the second number can't be zero!") # 二:捕獲異常後,抑制異常 class MuffledCalculator: muffled = False def calc(self, expr): try: return eval(expr) except ZeroDivisionError: if self.muffled: # 與使用者互動時,啟用抑制功能,不讓異常繼續傳播 print('Division by zero is illegal') else: # 在程式內部使用時,關閉抑制功能,引發異常 raise # 注意:發生除零行為,若啟用抑制功,calc將隱式地返回None。 # 三:在except子句中,引發別的異常 try: 1 / 0 except ZeroDivisionError: raise ValueError # 進行except子句的異常將被作為異常上下文儲存起來,並出現在最終的錯誤訊息中 # 四:使用None來禁用上下文 try: 1 / 0 except ZeroDivisionError: raise ValueError from None # 執行結果如下: Traceback(most recent call last): File"<stdin>", line 3, in <module> ValueError
其他用法:
# 一、多個except子句,捕獲多種異常
try:
x = int(input('first number:'))
y = int(input('second number:'))
print(x / y)
except ZeroDivisionError:
print("the second number can't be zero!")
except TypeError:
print("That wasn't a number, was it")
# 二、一個except子句捕獲多個異常,可在元組中指定異常(一個引數)
try:
x = int(input('first number:'))
y = int(input('second number:'))
print(x / y)
except (ZeroDivisionError, TypeError, NameError):
print("your numbers were bogus ...")
# 三、捕獲異常物件本身(可使用兩個引數)
try:
x = int(input('first number:'))
y = int(input('second number:'))
print(x / y)
except (ZeroDivisionError, TypeError) as e:
print(e) # 列印異常並繼續執行
# 四、捕獲所有異常,在except中不指定任何異常類即可
try:
x = int(input('first number:'))
y = int(input('second number:'))
print(x / y)
except:
print('something wrong happened ...')
# 這種做法很危險,會捕獲到使用者使用ctrl+c或呼叫函式sys.exit來終止執行的企圖等。推薦使用except Exception as e對異常物件進行檢查。(可能會讓不是從Exception派生而來的異常漏網,如SystemExit、KeyboardInterrupt,他們是從Exception的超類BaseException派生而來)
# 五、給try/except新增else子句和finally:沒有出現異常時會執行else中程式碼塊
x = None
try:
x = 1 / 0
except NameError:
print('unknown variable')
else:
print("that went well!")
finally:
print("cleaning up...")
del x # 發生異常時,執行finally子句清理工作(適用於確保檔案或網路套接字等得以關閉)
4、異常之禪
很多情況下,相比使用if/else,使用try/except語句更自然,也更符合python風格。(直接去做,有問題在處理,而不是預先做大量的檢查)