摘要:作為 Python 初學者,在剛學習 Python 編程時,經常會看到一些報錯信息,本文專門介紹 python 異常處理。
異常
- 廣義上的錯誤分為錯誤和異常
- 錯誤指的是可以人為避免
- 異常是指在語法邏輯正確的而前提下,出現的問題
- 在python中,異常是一個類,可以處理和使用
異常的分類
BaseException 所有異常的基類 Exception 常見錯誤的基類 ArithmeticError 所有數值計算錯誤的基類 Warning 警告的基類 AssertError 斷言語句(assert)失敗 AttributeError 嘗試訪問未知的對象屬性 DeprecattionWarning 關於被棄用的特征的警告 EOFError 用戶輸入文件末尾標志EOF(Ctrl+d) FloattingPointError 浮點計算錯誤 FutureWarning 關於構造將來語義會有改變的警告 GeneratorExit generator.close()方法被調用的時候 ImportError 導入模塊失敗的時候 IndexError 索引超出序列的范圍 KeyError 字典中查找一個不存在的關鍵字 KeyboardInterrupt 用戶輸入中斷鍵(Ctrl+c) MemoryError 內存溢出(可通過刪除對象釋放內存) NamerError 嘗試訪問一個不存在的變量 NotImplementedError 尚未實現的方法 OSError 操作系統產生的異常(例如打開一個不存在的文件) OverflowError 數值運算超出最大限制 OverflowWarning 舊的關於自動提升為長整型(long)的警告 PendingDeprecationWarning 關於特征會被遺棄的警告 ReferenceError 弱引用(weak reference)試圖訪問一個已經被垃圾回收機制回收了的對象 RuntimeError 一般的運行時錯誤 RuntimeWarning 可疑的運行行為(runtime behavior)的警告 StopIteration 迭代器沒有更多的值 SyntaxError Python的語法錯誤 SyntaxWarning 可疑的語法的警告 IndentationError 縮進錯誤 TabError Tab和空格混合使用 SystemError Python編譯器系統錯誤 SystemExit Python編譯器進程被關閉 TypeError 不同類型間的無效操作 UnboundLocalError 訪問一個未初始化的本地變量(NameError的子類) UnicodeError Unicode相關的錯誤(ValueError的子類) UnicodeEncodeError Unicode編碼時的錯誤(UnicodeError的子類) UnicodeDecodeError Unicode解碼時的錯誤(UnicodeError的子類) UserWarning 用戶代碼生成的警告 ValueError 傳入無效的參數 ZeroDivisionError 除數為零
l = [1,2,3,4,5] # 除零錯誤 num = int(input("Please input your num: ")) print(100/num)
Please input your num: 0 --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-1-8abb196ce2aa> in <module> 2 # 除零錯誤 3 num = int(input("Please input your num: ")) ----> 4 print(100/num) ZeroDivisionError: division by zero
異常處理
- 不能保證程序永遠正確運行
- 但是,必須保證程序在最壞的情況下得到的問題被妥善管理
- python的異常處理模塊全部語法為:
try: 嘗試實現某個操作, 如果沒有出現異常,任務就可以完成 如果出現異常,將異常從當前代碼塊扔出去嘗試解決異常 except 異常類型1: 解決方案1:用於嘗試在此處處理異常解決問題 except 異常類型2: 解決方案2:用於嘗試在此處處理異常解決問題 except (異常類型1,異常類型2...): 解決方案:針對多個異常使用相同的處理方式 except: 如果沒有出現任何異常,將會執行此處代碼 finally: 有沒有異常都要執行的代碼
- 流程
- 執行try下面的語句
- 如果出現異常,則在except語句里查找對應異常病進行處理
- 如果沒有出現異常,則執行else語句內容
- 最后,不管是否出現異常,都要執行finally語句
- 除except(最少一個)以外,else和finally可選
# 簡單異常案例 try: num = int(input("Please input your number:")) rst = 100/num print("計算結果是:{}".format(rst)) except: print("輸入錯誤") # exit是退出程序的意思 exit()
Please input your number:0 輸入錯誤
# 簡單異常案例 # 給出提示信息 try: num = int(input("Please input your number:")) rst = 100/num print("計算結果是:{}".format(rst)) # 捕獲異常后,把異常實例化,出錯信息會在實例里 # 注意以下寫法 # 以下語句是捕獲ZeroDivisionError異常並實例化實例e except ZeroDivisionError as e: print("輸入錯誤") print(e) # exit是退出程序的意思 exit()
# 簡單異常案例 # 給出提示信息 try: num = int(input("Please input your number:")) rst = 100/num print("計算結果是:{}".format(rst)) # 如果是多種error的情況 # 需要把越具體的錯誤,越往前放 # 在異常類繼承關系中,越是子類的異常,越要往前放, # 越是父類的異常,越要往后放 、 # 在處理異常的時候,一旦攔截到某一個異常,則不再繼續往下查看,直接進行下一個 # 代碼,即有finally則執行finally語句,否賊就執行下一個大的語句 except ZeroDivisionError as e: print("輸入錯誤") print(e) # exit是退出程序的意思 exit() except NameError as e: print("名字起錯了") print(e) except AttributeError as e: print("屬性錯誤") print(e) exit() # 常見錯誤的基類 # 如果寫下面這句話,常見異常都會攔截住 # 而且下面這句話一定是最后一個excepttion except Exception as e: print("我也不知道就出錯了") print(e) except ValueError as e: print("NO>>>>>>>>>>>") print("hahaha")
Please input your number:ffff 我也不知道就出錯了 invalid literal for int() with base 10: 'ffff' hahaha
用戶手動引發異常
- 當某些情況,用戶希望自己引發一個異常的時候,可以使用
- raise 關鍵字來引發異常
# raise 案例 try: print("I love you") print(3.1415926) # 手動引發一個異常 # 注意語法:raise ErrorClassName raise ValueError print("還沒完呀") except NameError as e: print("NameError") except ValueError as e: print("ValueError") except Exception as e: print("有異常") finally: print("我肯定會被執行的")
I love you 3.1415926 ValueError 我肯定會被執行的
# raise 案例-2 # 自定義異常 # 需要注意:自定義異常必須是系統異常的子類 class DanaValueError(ValueError): pass try: print("I love you") print(3.1415926) # 手動引發一個異常 # 注意語法:raise ErrorClassName raise DanaValueError print("還沒完呀") except NameError as e: print("NameError") # except DanaValueError as e: # print("DanaError") except ValueError as e: print("ValueError") except Exception as e: print("有異常") finally: print("我肯定會被執行的")
I love you 3.1415926 ValueError 我肯定會被執行的
# else語句案例 try: num = int(input("Please input your number:")) rst = 100/num print("計算結果是:{}".format(rst)) except Exception as e: print("Exceptiong") else: print("No Exception") finally: print("反正我會被執行")
Please input your number:0 Exceptiong 反正我會被執行
關於自定義異常
- 只要是raise異常,則推薦自定義異常
- 在自定義異常的時候,一般包含以下內容:
- 自定義發生異常的異常代碼
- 自定義發生異常后的問題提示
- 自定義發生異常的行數
- 最終的目的是,一旦發生異常,方便程序員快速定位錯誤現場
本文分享自華為雲社區《一文集結 python 異常處理》,原文作者:ruochen。