Python異常捕獲與處理

2021-12-28 怕蛇的人怎麼學Python
什麼是異常?

異常即是一個事件,該事件會在程序執行過程中發生,影響了程序的正常執行。一般情況下,在Python無法正常處理程序時就會發生一個異常。異常是Python對象,表示一個錯誤。當Python腳本發生異常時我們需要捕獲處理它,否則程序會終止執行。

當一個未捕獲的異常發生時,Python將結束程序並列印一個堆棧跟蹤信息,以及異常名和附加信息。具體如下:

Traceback (most recent call last): File "<pyshell#1>", line 1, in <module>ZeroDivisionError: division by zero

廣義上的錯誤分為錯誤和異常

錯誤通常指的是語法錯誤,可以人為避免

異常是指在語法邏輯正確的而前提下,出現的問題

在Python中捕獲和處理異常的主要目的:

錯誤處理:在運行時出現錯誤的情況下,應用程式可能會無條件終止。使用異常處理,我們可以處理失敗的情況並避免程序終止。

代碼分離:錯誤處理可以幫助我們將錯誤處理所需的代碼與主邏輯分離。與錯誤相關的代碼可以放置在「 except 」塊中,該塊將其與包含應用程式邏輯的常規代碼隔離開來。

錯誤區分:幫助我們隔離執行過程中遇到的不同類型的錯誤。我們可以有多個「 except」塊,每個塊處理一種特定類型的錯誤。

其他方面的應用:

事件通知:異常也可以作為某種條件的信號,而不需要在程序裡傳送結果標誌或顯式地測試它們。

特殊情形處理:有時有些情況是很少發生的,把相應的處理代碼改為異常處理會更好一些。

特殊的控制流:異常是一個高層次的」goto」,可以把它作為實現特殊控制流的基礎。如反向跟蹤等。

Python自帶的異常處理機制非常強大,提供了很多內置異常類,可向用戶準確反饋出錯信息。Python是面向對象語言,認為一切皆對象,所以異常也是對象。Python異常處理機制中的BaseException是所有內置異常的基類,但用戶定義的類並不直接繼承BaseException,所有的異常類都是從Exception繼承,且都在exceptions模塊中定義。Python自動將所有異常名稱放在內建命名空間中,所以程序不必導入exceptions模塊即可使用異常。

Python內置異常類繼承層次結構如下:

-- SystemExit  # 解釋器請求退出-- KeyboardInterrupt  # 用戶中斷執行(通常是輸入^C)-- GeneratorExit  # 生成器(generator)發生異常來通知退出     -- StopIteration  # 迭代器沒有更多的值     -- StopAsyncIteration  # 必須通過異步迭代器對象的__anext__()方法引發以停止迭代     -- ArithmeticError  # 各種算術錯誤引發的內置異常的基類     |    -- FloatingPointError  # 浮點計算錯誤     |    -- OverflowError  # 數值運算結果太大無法表示     |    -- ZeroDivisionError  # 除(或取模)零 (所有數據類型)     -- AssertionError  # 當assert語句失敗時引發     -- AttributeError  # 屬性引用或賦值失敗     -- BufferError  # 無法執行與緩衝區相關的操作時引發     -- EOFError  # 當input()函數在沒有讀取任何數據的情況下達到文件結束條件(EOF)時引發     -- ImportError  # 導入模塊/對象失敗     |    -- ModuleNotFoundError  # 無法找到模塊或在在sys.modules中找到None     -- LookupError  # 映射或序列上使用的鍵或索引無效時引發的異常的基類     |    -- IndexError  # 序列中沒有此索引(index)     |    -- KeyError  # 映射中沒有這個鍵     -- MemoryError  # 內存溢出錯誤(對於Python 解釋器不是致命的)     -- NameError  # 未聲明/初始化對象 (沒有屬性)     |    -- UnboundLocalError  # 訪問未初始化的本地變量     -- OSError  # 作業系統錯誤,EnvironmentError,IOError,WindowsError,socket.error,select.error和mmap.error已合併到OSError中,構造函數可能返回子類     |    -- BlockingIOError  # 操作將阻塞對象(e.g. socket)設置為非阻塞操作     |    -- ChildProcessError  # 在子進程上的操作失敗     |    -- ConnectionError  # 與連接相關的異常的基類     |    |    -- BrokenPipeError  # 另一端關閉時嘗試寫入管道或試圖在已關閉寫入的套接字上寫入     |    |    -- ConnectionAbortedError  # 連接嘗試被對等方中止     |    |    -- ConnectionRefusedError  # 連接嘗試被對等方拒絕     |    |    -- ConnectionResetError    # 連接由對等方重置     |    -- FileExistsError  # 創建已存在的文件或目錄     |    -- FileNotFoundError  # 請求不存在的文件或目錄     |    -- InterruptedError  # 系統調用被輸入信號中斷     |    -- IsADirectoryError  # 在目錄上請求文件操作(例如 os.remove())     |    -- NotADirectoryError  # 在不是目錄的事物上請求目錄操作(例如 os.listdir())     |    -- PermissionError  # 嘗試在沒有足夠訪問權限的情況下運行操作     |    -- ProcessLookupError  # 給定進程不存在     |    -- TimeoutError  # 系統函數在系統級別超時     -- ReferenceError  # weakref.proxy()函數創建的弱引用試圖訪問已經垃圾回收了的對象     -- RuntimeError  # 在檢測到不屬於任何其他類別的錯誤時觸發     |    -- NotImplementedError  # 在用戶定義的基類中,抽象方法要求派生類重寫該方法或者正在開發的類指示仍然需要添加實際實現     |    -- RecursionError  # 解釋器檢測到超出最大遞歸深度     -- SyntaxError  # Python 語法錯誤     |    -- IndentationError  # 縮進錯誤     |         -- TabError  # Tab和空格混用     -- SystemError  # 解釋器發現內部錯誤     -- TypeError  # 操作或函數應用於不適當類型的對象     -- ValueError  # 操作或函數接收到具有正確類型但值不合適的參數     |    -- UnicodeError  # 發生與Unicode相關的編碼或解碼錯誤     |         -- UnicodeDecodeError  # Unicode解碼錯誤     |         -- UnicodeEncodeError  # Unicode編碼錯誤     |         -- UnicodeTranslateError  # Unicode轉碼錯誤     -- Warning  # 警告的基類          -- DeprecationWarning  # 有關已棄用功能的警告的基類          -- PendingDeprecationWarning  # 有關不推薦使用功能的警告的基類          -- RuntimeWarning  # 有關可疑的運行時行為的警告的基類          -- SyntaxWarning  # 關於可疑語法警告的基類          -- UserWarning  # 用戶代碼生成警告的基類          -- FutureWarning  # 有關已棄用功能的警告的基類          -- ImportWarning  # 關於模塊導入時可能出錯的警告的基類          -- UnicodeWarning  # 與Unicode相關的警告的基類          -- BytesWarning  # 與bytes和bytearray相關的警告的基類          -- ResourceWarning  # 與資源使用相關的警告的基類。被默認警告過濾器忽略。

異常捕獲與處理

我們不能保證編寫的程序永遠正確運行,異常捕獲與處理的宗旨是保證程序在最壞的情況下得到的問題被妥善管理。

try:
可能產生異常的代碼塊
except [ (Error1, Error2, ... ) [as e] ]:
處理異常的代碼塊1
except [ (Error3, Error4, ... ) [as e] ]:
處理異常的代碼塊2
except [Exception]:
處理其它異常
else:
沒有異常時執行的代碼塊
finally:
不管有沒有異常都會執行的代碼塊

try:    可能產生異常的代碼塊except [ (Error1, Error2, ... ) [as e] ]:    處理異常的代碼塊1except [ (Error3, Error4, ... ) [as e] ]:    處理異常的代碼塊2except  [Exception]:    處理其它異常else:    沒有異常時執行的代碼塊finally:    不管有沒有異常都會執行的代碼塊

try的工作原理是,當開始一個try語句後,python就在當前程序的上下文中作標記,這樣當異常出現時就可以回到這裡,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。

如果當try後的語句執行時發生異常,Python就跳回到try並執行第一個匹配該異常的except子句,異常處理完畢,控制流就通過整個try語句(除非在處理異常時又引發新的異常)。如果在try後的語句裡發生了異常,卻沒有匹配的except子句,異常將被遞交到上層的try,或者到程序的最上層(這樣將結束程序,並列印預設的出錯信息)。如果在try子句執行時沒有發生異常,Python將執行else語句後的語句(如果有else的話),然後控制流通過整個try語句。

代碼實例:

try:    file_reader = open("a.json")    print(file_reader.read())except FileNotFoundError:    print("The File Cannot be Found")except:    print("This is the Generic Error")finally:    print("Closing File Reader...")    file_reader.close()

Exception類是所有Python異常類的父類,所以except Exception將可以捕獲任何異常,換句話說,它是萬能異常處理句式。有一種錯誤沒辦法抓住:縮進錯誤。

raise:手動引發異常

有時候,異常可以作為代碼運行的標誌,通過主動觸發異常可以改變代碼的運行路線,從而提高代碼健壯性。

主動觸發異常需使用raise關鍵字,其語法結構如下:

raise [Exception [, args [, traceback]]]

示例:

try:    a = int(input("Enter a positive integer value: "))    if a <= 0:        raise ValueError("This is not a positive number!!")except ValueError as ve:    print(ve)

語句中Exception是異常的類型(例如,ValueError)參數是一個異常參數值。該參數是可選的,如果不提供,異常的參數是」None」。最後一個參數是可選的(在實踐中很少使用),如果存在,是跟蹤異常對象。

自定義異常

你可以通過創建一個新的異常類來擁有自己的異常。異常類繼承自 Exception 類,可以直接繼承,或者間接繼承,例如:

class MyError(Exception):   def __init__(self, value):       self.value = value       return repr(self.value)      print('My exception occurred, value:', e.value)

斷言:assert條件

Python assert(斷言)用於判斷一個表達式,在表達式條件為 false 的時候觸發異常。斷言可以在條件不滿足程序運行的情況下直接返回錯誤,而不必等待程序運行後出現崩潰的情況,例如我們的代碼只能在 Linux 系統下運行,可以先判斷當前系統是否符合條件。

語法格式如下:

等價於:

if not expression:    raise AssertionError(arguments)

實例:

import sysassert ('linux' in sys.platform), "該代碼只能在 Linux 下執行"

assert看上去不錯,然而用起來並不爽。就比如有人告訴你程序錯了,但是不告訴哪裡錯了。很多時候這樣的assert還不如不寫。常見方案是使用測試框架或其他包代替:py.test、unittest、ptest、assertpy…

traceback 獲取詳細的異常信息

try…except…的輸出結果只能讓你知道報了這個錯誤,卻不知道在哪個文件哪個函數哪一行報的錯。使用 traceback 模塊可以非常清楚的了解具體錯誤內容在哪:

import traceback
try: 1 / 0except Exception as e: traceback.print_exc()

輸出:

Traceback (most recent call last):File "test_traceback.py", line 3, in <module>1/0ZeroDivisionError: integer division or modulo by zero

Python程序的traceback信息均來源於一個叫做traceback object的對象,而這個traceback object通常是通過函數sys.exc_info()來獲取的:

import sys

def func1(): raise Exception("--func1 exception--")

def test1(): try: func1() except Exception as e: print(e)

def test2(): try: func1() except Exception as e: exc_type, exc_value, exc_traceback_obj = sys.exc_info() print("exc_type: %s" % exc_type) print("exc_value: %s" % exc_value) print("exc_traceback_obj: %s" % exc_traceback_obj)

if __name__ == '__main__': test1() test2()

輸出結果:

--func1 exception--exc_type: <class 'Exception'>exc_value: --func1 exception--exc_traceback_obj: <traceback object at 0x0000024D2F6A22C8>
Process finished with exit code 0

通過以上示例我們可以看出,sys.exc_info()獲取了當前處理的exception的相關信息,並返回一個元組,元組的第一個數據是異常的類型,第二個返回值是異常的value值,第三個就是我們要的traceback object.

有了traceback object我們就可以通過traceback module來列印和格式化traceback的相關信息。

參考連結:

錯誤和異常

traceback — 列印或檢索堆棧回溯                                            

相關焦點

  • python中的異常捕獲
    ,比如除數為0的異常,可能初次測試時被除數都不為0,開發者就認為代碼是ok的,但是當處理的項目多了,某一天處理了一個除數為0的事務時,代碼報錯了,此時才意識到代碼存在bug, 這也是為什麼軟體開發不能一步到位,而是不斷迭代升級的原因,只有當代碼處理的項目足夠多的,範圍足夠廣,才能夠發現現有代碼的不足,從而做出改進。
  • python面向對象之異常處理
    異常的概念 程序在運行時,如果 `Python 解釋器` 遇到 到一個錯誤,會停止程序的執行,並且提示一些錯誤信息,這就是 異常 程序停止執行並且提示錯誤信息 這個動作,我們通常稱之為:拋出(raise)異常> 程序開發時,很難將 所有的特殊情況 都處理的面面俱到,通過 異常捕獲 可以針對突發事件做集中的處理,從而保證程序的 穩定性和健壯性
  • python 異常處理
    當Python檢測到一個錯誤時,解釋器就無法繼續執行了,反而出現了一些錯誤的提示,這就是所謂的"異常"捕獲異常<1>捕獲異常 try...except...看如下示例:try: print('test--1---') open('123.txt','r') print('test--2---')except IOError: pass說明:此程序看不到任何錯誤,因為用except 捕獲到了IOError異常,並添加了處理的方法pass 表示實現了相應的實現,但什麼也不做;如果把pass
  • python學習筆記(9): try...except 異常捕獲
    目前正在學習python基礎,同時也在leetcode-cn上刷算法題目,有興趣的同學一起哦。最近學習了python如何處理異常,發現一篇比較好的文章,整理了一下,供大家學習研究。一、什麼是異常?當無法正確處理程序時就會出現異常。當異常發生時我們需要捕獲處理它,否則程序會終止執行。
  • python入門——Python中異常處理
    python大數據課堂已經開始了。想轉行大數據,數據挖掘,機器學習,人工智慧的小夥伴可以關注啦。上一篇帶大家了解了python中的I/O函數。今天我們來繼續了解python中的異常處理。調試環境以python3.6環境為例。需要代碼和demo的朋友可以搜索「欒鵬全棧」到我的CSDN博客。
  • python異常處理與上下文管理器
    異常處理異常與錯誤錯誤可以通過IDE或者解釋器給出提示的錯誤opentxt('a.jpg','r')語法層面沒有問題,但是自己代碼的邏輯有問題if age>18: print('未成年')異常多指在程序執行過程中,出現的未知錯誤,語法和邏輯本身是正確的。
  • python入門學習異常處理類型
    前言異常是指在程序執行過程中發生的一個事件,影響了程序的正常執行,例如:0做了分母。異常是Python對象,表示一個錯誤。當Python腳本發生異常時我們需要捕獲處理它,否則程序會終止執行。在Java語言中我們知道異常的常用結構為try catch組成,有時也會用到finally,那麼在python中異常是如何來處理的呢?python中的異常處理1.python異常簡單語法python異常的簡單語法為try-except-else語法,注意這裡的關鍵字是except而不是Exception,這與java是有區別的。
  • python異常的捕獲與傳遞
    as errorMsg: print('產生錯誤了:%s'%errorMsg)else: print('沒有捕獲到異常,真高興')運行結果如下:<6> try...finally...,信息是:%s"%result) print("----test3-2----") test3() print("-華麗的分割線") test2()運行結果:總結:如果try嵌套,那麼如果裡面的try沒有捕獲到這個異常,那麼外面的try會接收到這個異常,然後進行處理,如果外邊的try依然沒有捕獲到,那麼再進行傳遞。。。
  • 十、python基礎之異常處理結構與程序調試方法
    實驗目的:學習python的異常處理和程序調試實驗環境:已正確安裝python3.51、異常的基本概念異常是指程序運行時引發的錯誤,得不到正確的處理將會導致程序終止運行合理地使用異常處理結構可以使得程序更加健壯,具有更強的容錯性。例如:最常見的除數為0,python會拋出「ZeroDivisionError"異常。
  • 一篇文章幫你搞定Python異常處理
    =1+'str'什麼是異常異常就是程序運行時發生錯誤的信號,在python中,錯誤觸發的異常如下Python中異常種類在python中不同的異常可以用不同的類型(python中統一了類與類型,類型即類)去標識,不同的類對象標識不同的異常,一個異常標識一種錯# 觸發IndexErrorl=['run1','aa']
  • python妙招-異常處理之try-except
    Python中檢測處理異常是非常重要的,這可以增加代碼的健壯性,我們在寫python程序的時候,會可能會遇到一些不可預料的情況,一旦遇到這些情況,運行時程序便可能會崩潰。比如:讀寫文件時候文件打開錯誤或者文件寫入錯誤,寫爬蟲時網絡請求失敗,返回錯誤404.再或者函數處理一些不確定參數時候,都可以用到異常捕獲。
  • WinForm捕獲全局異常(捕獲未處理的異常)
    背景我們在做WinForm程序的時候,一般都是對異常進行處理
  • Python 異常處理
    前言程序設計總是會報錯的,之前有談過幾次異常的處理,現在再來說一說:什麼是異常?當 Python 檢測到一個錯誤時,解釋器就無法繼續執行了,並且給出一個錯誤提示。比如寫入文件的時候,磁碟滿了,寫不進去了,或者從網絡抓取數據,網絡突然中斷。
  • 基礎 | Java 中的異常捕獲及處理
    為了能夠及時有效地處理程序中的運行錯誤,Java 專門引入了異常類。Throwable 類是所有異常和錯誤的超類,下面有 Error 和 Exception 兩個子類分別表示錯誤和異常。我們不討論關於 Error 類型的異常處理,因為它們通常是災難性的致命錯誤,不是程序可以控制的。
  • 一文讀懂Python中的異常處理
    ,良好的異常處理可以讓你的程序更加健壯,清晰的錯誤信息更能幫助你快速修復問題。except語句後面如果不指定異常類型,則默認捕獲所有異常,你可以通過logging或者sys模塊獲取當前異常。如果要捕獲異常後要重複拋出,請使用raise,後面不要帶任何參數或信息。
  • Python異常處理
    問題描述大家在使用python語言寫代碼的時候難免會出一些錯誤,而才入門的朋友們往往不知道是哪裡出了錯或者不知道自己錯在哪裡、什麼錯誤。所以我們要知道是哪行代碼出錯,其次室錯誤的類型是什麼,錯在那個細節,逐步分析,從而解決錯誤並改正。
  • Python學習第50課-處理錯誤和異常
    【每天幾分鐘,從零入門python編程的世界!】在工作當中會經常出現意料不到的錯誤和異常,就需要我們對可能出現的錯誤和異常進行預判,然後加上捕獲和處理錯誤異常的代碼,否則,程序在運行過程中,遇到錯誤和異常就會crash崩潰,無法繼續向下執行。●Python的錯誤種類:①語法錯誤,或稱解析錯誤。
  • python基礎---異常處理
    程序的異常處理今天霖小白心血來潮想來分享一下python基礎中的如何異常處理,使程序有更好的用戶體驗。前言python程序對用戶的輸入有一定的要求,所以當實際輸入不滿足程序要求時,可能在程序運行過程中會直接報錯無法進行下一步的運行。
  • 未雨綢繆-Python異常
    為處理這些異常事件,可在每個可能發生這些事件的地方都使用條件語句。例如,對於每個除法運算,都檢查除數是否為零。然而,這樣做不僅效率低下、缺乏靈活性,還可能導致程序難以卒讀。1 異常是什麼Python使用異常對象來表示異常狀態,並在遇到錯誤時引發異常。異常對象未被處理(或捕獲)時,程序將終止並顯示一條錯誤消息(traceback)。
  • python異常處理筆記
    收錄於話題 #python What:python異常處理是什麼?