內建異常

在 Python 中,所有異常都必須是派生自 BaseException 的類的例項。在帶有 except 子句(其中提到了某個特定類)的 try 語句中,該子句也會處理從該類派生的任何異常類(但不會處理其派生類)。兩個透過子類化不相關的異常類永遠不等價,即使它們具有相同的名稱。

本章中列出的內建異常可以由直譯器或內建函式生成。除非另有說明,它們具有一個“關聯值”,指示錯誤的詳細原因。這可能是一個字串或一個包含多個資訊項的元組(例如,一個錯誤程式碼和一個解釋該程式碼的字串)。關聯值通常作為引數傳遞給異常類的建構函式。

使用者程式碼可以引發內建異常。這可用於測試異常處理程式,或報告“就像”直譯器引發相同異常一樣的情況下的錯誤條件;但請注意,沒有什麼能阻止使用者程式碼引發不適當的錯誤。

內建異常類可以被子類化以定義新的異常;鼓勵程式設計師從 Exception 類或其子類之一派生新異常,而不是從 BaseException 派生。有關定義異常的更多資訊,請參閱 Python 教程中的 使用者自定義異常

異常上下文

異常物件上的三個屬性提供有關引發異常的上下文資訊

BaseException.__context__
BaseException.__cause__
BaseException.__suppress_context__

當在處理另一個異常時引發新異常時,新異常的 __context__ 屬性會自動設定為正在處理的異常。當使用 exceptfinally 子句,或者 with 語句時,異常可能正在被處理。

這種隱式異常上下文可以透過在 raise 語句中使用 from 來補充顯式原因

raise new_exc from original_exc

from 之後的表示式必須是一個異常或 None。它將被設定為引發異常的 __cause__。設定 __cause__ 還會隱式地將 __suppress_context__ 屬性設定為 True,這樣,對於顯示目的(例如,將 KeyError 轉換為 AttributeError),使用 raise new_exc from None 實際上是用新異常替換舊異常,同時將舊異常保留在 __context__ 中,以便在除錯時進行內省。

預設的 traceback 顯示程式碼除了異常本身的 traceback 外,還會顯示這些鏈式異常。當存在時,__cause__ 中顯式鏈式異常總是顯示。只有當 __cause__None 並且 __suppress_context__ 為假時,__context__ 中隱式鏈式異常才顯示。

無論哪種情況,異常本身總是顯示在任何鏈式異常之後,以便 traceback 的最後一行總是顯示最後引發的異常。

繼承內建異常

使用者程式碼可以建立繼承自異常型別的子類。建議一次只子類化一種異常型別,以避免基類處理 args 屬性的任何可能衝突,以及由於可能存在的記憶體佈局不相容性。

CPython 實現細節: 大多數內建異常都是為了效率而在 C 中實現的,參見:Objects/exceptions.c。有些具有自定義記憶體佈局,這使得無法建立繼承自多個異常型別的子類。型別的記憶體佈局是實現細節,可能會在 Python 版本之間更改,從而導致未來出現新的衝突。因此,建議完全避免子類化多個異常型別。

基類

以下異常主要用作其他異常的基類。

exception BaseException

所有內建異常的基類。它不應直接由使用者自定義類繼承(為此,請使用 Exception)。如果對該類的例項呼叫 str(),則返回例項引數的表示形式,如果沒有引數則返回空字串。

args

傳遞給異常建構函式的引數元組。一些內建異常(如 OSError)期望特定數量的引數並對該元組的元素賦予特殊含義,而其他異常通常只帶一個字串作為錯誤訊息。

with_traceback(tb)

此方法將 *tb* 設定為異常的新回溯並返回異常物件。它在 PEP 3134 的異常鏈特性可用之前更常用。以下示例展示瞭如何在保留回溯的同時將 SomeException 的例項轉換為 OtherException 的例項。一旦引發,當前幀就會被推入 OtherException 的回溯中,就像如果允許它傳播到呼叫者,原始 SomeException 的回溯會發生的那樣。

try:
    ...
except SomeException:
    tb = sys.exception().__traceback__
    raise OtherException(...).with_traceback(tb)
__traceback__

一個可寫欄位,儲存與此異常關聯的 回溯物件。另請參閱:raise 語句

add_note(note)

將字串 note 新增到異常的註釋中,這些註釋在標準追溯中顯示在異常字串之後。如果 note 不是字串,則會引發 TypeError

在 3.11 版本中新增。

__notes__

此異常的註釋列表,這些註釋透過 add_note() 新增。此屬性在呼叫 add_note() 時建立。

在 3.11 版本中新增。

exception Exception

所有內建的、非系統退出異常都派生自此類。所有使用者定義的異常也應該派生自此類。

exception ArithmeticError

用於各種算術錯誤而引發的內建異常的基類:OverflowErrorZeroDivisionErrorFloatingPointError

exception BufferError

當無法執行與 緩衝區 相關的操作時引發。

exception LookupError

當在對映或序列上使用的鍵或索引無效時引發的異常的基類:IndexErrorKeyError。這可以直接由 codecs.lookup() 引發。

具體異常

以下異常是通常會引發的異常。

exception AssertionError

assert 語句失敗時引發。

exception AttributeError

當屬性引用(參見 屬性引用)或賦值失敗時引發。(當物件根本不支援屬性引用或屬性賦值時,將引發 TypeError。)

可選的 *name* 和 *obj* 僅限關鍵字引數設定相應的屬性

name

嘗試訪問的屬性的名稱。

obj

被訪問以獲取命名屬性的物件。

3.10 版中已更改: 添加了 nameobj 屬性。

exception EOFError

input() 函式在未讀取任何資料的情況下遇到檔案結束條件 (EOF) 時引發。(注意:io.IOBase.read()io.IOBase.readline() 方法在遇到 EOF 時返回空字串。)

exception FloatingPointError

目前未使用。

exception GeneratorExit

生成器協程 關閉時引發;參見 generator.close()coroutine.close()。它直接繼承自 BaseException 而不是 Exception,因為它在技術上不是一個錯誤。

exception ImportError

import 語句在嘗試載入模組時遇到問題時引發。當 from ... import 中的“from list”包含找不到的名稱時也會引發。

可選的 *name* 和 *path* 僅限關鍵字引數設定相應的屬性

name

嘗試匯入的模組的名稱。

path

觸發異常的任何檔案的路徑。

3.3 版中已更改: 添加了 namepath 屬性。

exception ModuleNotFoundError

ImportError 的子類,當無法找到模組時由 import 引發。當 sys.modules 中發現 None 時也會引發。

在 3.6 版本加入。

exception IndexError

當序列下標超出範圍時引發。(切片索引會自動截斷到允許的範圍;如果索引不是整數,則會引發 TypeError。)

exception KeyError

當對映(字典)鍵在現有鍵集中找不到時引發。

exception KeyboardInterrupt

當用戶按下中斷鍵(通常是 Control-CDelete)時引發。在執行期間,會定期檢查中斷。該異常繼承自 BaseException,以避免被捕獲 Exception 的程式碼意外捕獲,從而阻止直譯器退出。

備註

捕獲 KeyboardInterrupt 需要特別考慮。因為它可能在不可預測的時間點引發,所以在某些情況下,它可能會使正在執行的程式處於不一致的狀態。通常最好讓 KeyboardInterrupt 儘快終止程式,或完全避免引發它。(參見 訊號處理程式和異常的注意事項。)

exception MemoryError

當操作記憶體不足但情況仍可能被挽救(透過刪除一些物件)時引發。關聯值是一個字串,指示哪種(內部)操作記憶體不足。請注意,由於底層記憶體管理架構(C 的 malloc() 函式),直譯器可能不總是能夠完全從這種情況中恢復;但它仍然會引發異常,以便可以列印堆疊回溯,以防失控程式是原因。

exception NameError

當找不到本地或全域性名稱時引發。這僅適用於非限定名稱。關聯值是包含找不到的名稱的錯誤訊息。

可選的 *name* 僅限關鍵字引數設定屬性

name

嘗試訪問的變數的名稱。

3.10 版中已更改: 添加了 name 屬性。

exception NotImplementedError

此異常派生自 RuntimeError。在使用者定義的基類中,當抽象方法要求派生類覆蓋該方法時,或者在類開發過程中表示實際實現仍需新增時,應引發此異常。

備註

它不應用於表示運算子或方法根本不應受支援的情況——在這種情況下,要麼保留運算子/方法未定義,要麼(如果是子類)將其設定為 None

注意

NotImplementedErrorNotImplemented 不可互換。此異常僅應如上所述使用;有關內建常量的正確用法,請參閱 NotImplemented

exception OSError([arg])
exception OSError(errno, strerror[, filename[, winerror[, filename2]]])

當系統函式返回與系統相關的錯誤時引發此異常,包括 I/O 故障,如“檔案未找到”或“磁碟已滿”(不適用於非法引數型別或其他意外錯誤)。

建構函式的第二種形式設定了下面描述的相應屬性。如果未指定,屬性預設為 None。為了向後相容,如果傳遞了三個引數,則 args 屬性只包含前兩個建構函式引數的 2 元組。

建構函式通常實際上返回 OSError 的子類,如下面的 OS 異常 中所述。特定的子類取決於最終的 errno 值。此行為僅在直接或透過別名構造 OSError 時發生,並且在子類化時不會繼承。

errno

來自 C 變數 errno 的數字錯誤程式碼。

winerror

在 Windows 下,這會提供本機 Windows 錯誤程式碼。errno 屬性是該本機錯誤程式碼的近似翻譯,以 POSIX 術語表示。

在 Windows 下,如果 *winerror* 建構函式引數是一個整數,則 errno 屬性由 Windows 錯誤程式碼確定,並且 *errno* 引數被忽略。在其他平臺,*winerror* 引數被忽略,並且 winerror 屬性不存在。

strerror

相應的錯誤訊息,由作業系統提供。它由 C 函式 perror() (POSIX) 和 FormatMessage() (Windows) 格式化。

filename
filename2

對於涉及檔案系統路徑的異常(如 open()os.unlink()),filename 是傳遞給函式的原始檔名。對於涉及兩個檔案系統路徑的函式(如 os.rename()),filename2 對應於傳遞給函式的第二個檔名。

3.3 版中已更改: EnvironmentErrorIOErrorWindowsErrorsocket.errorselect.errormmap.error 已合併到 OSError 中,並且建構函式可能返回一個子類。

3.4 版中已更改: filename 屬性現在是傳遞給函式的原始檔名,而不是編碼或解碼自 檔案系統編碼和錯誤處理程式 的名稱。此外,還添加了 *filename2* 建構函式引數和屬性。

exception OverflowError

當算術運算的結果太大而無法表示時引發。這對於整數不會發生(整數寧願引發 MemoryError 也不放棄)。但是,出於歷史原因,對於超出所需範圍的整數有時會引發 OverflowError。由於 C 中浮點異常處理缺乏標準化,大多數浮點運算都不會被檢查。

exception PythonFinalizationError

此異常派生自 RuntimeError。當直譯器關閉期間(也稱為 Python 終結化)操作被阻塞時引發。

在 Python 終結化期間可能被 PythonFinalizationError 阻塞的操作示例

  • 建立一個新的 Python 執行緒。

  • Joining 一個正在執行的守護執行緒。

  • os.fork().

另請參閱 sys.is_finalizing() 函式。

3.13 版新增: 此前,會引發一個普通的 RuntimeError

3.14 版中已更改: threading.Thread.join() 現在可以引發此異常。

exception RecursionError

此異常派生自 RuntimeError。當直譯器檢測到超出最大遞迴深度(參見 sys.getrecursionlimit())時引發。

3.5 版新增: 此前,會引發一個普通的 RuntimeError

exception ReferenceError

當使用由 weakref.proxy() 函式建立的弱引用代理來訪問已經被垃圾回收的引用物件的屬性時,會引發此異常。有關弱引用的更多資訊,請參閱 weakref 模組。

exception RuntimeError

當檢測到不屬於任何其他類別的錯誤時引發。關聯值是一個字串,指示具體出了什麼問題。

exception StopIteration

由內建函式 next()迭代器__next__() 方法引發,以表示迭代器不再產生更多項。

value

異常物件有一個屬性 value,它在構造異常時作為引數給出,預設為 None

生成器協程 函式返回時,會引發一個新的 StopIteration 例項,並且函式返回的值將用作異常建構函式的 value 引數。

如果生成器程式碼直接或間接引發 StopIteration,它將被轉換為 RuntimeError(保留 StopIteration 作為新異常的原因)。

3.3 版中已更改: 添加了 value 屬性以及生成器函式使用它返回值的特性。

3.5 版中已更改: 透過 from __future__ import generator_stop 引入了 RuntimeError 轉換,參見 PEP 479

3.7 版中已更改: 預設情況下為所有程式碼啟用 PEP 479:生成器中引發的 StopIteration 錯誤將轉換為 RuntimeError

exception StopAsyncIteration

必須由 __anext__() 非同步迭代器物件的方法引發,以停止迭代。

在 3.5 版本加入。

exception SyntaxError(message, details)

當解析器遇到語法錯誤時引發。這可能發生在 import 語句中,呼叫內建函式 compile()exec()eval() 時,或者讀取初始指令碼或標準輸入(也包括互動式)時。

異常例項的 str() 只返回錯誤訊息。*details* 是一個元組,其成員也作為單獨的屬性可用。

filename

發生語法錯誤的檔名。

lineno

檔案中發生錯誤的行號。這是從 1 開始索引的:檔案中的第一行 lineno 為 1。

offset

行中發生錯誤的列。這是從 1 開始索引的:行中的第一個字元 offset 為 1。

text

錯誤中涉及的原始碼文字。

end_lineno

檔案中發生錯誤的結束行號。這是從 1 開始索引的:檔案中的第一行 lineno 為 1。

end_offset

錯誤結束所在的行中的列。這是從 1 開始索引的:行中的第一個字元 offset 為 1。

對於 f 字串欄位中的錯誤,訊息字首為“f-string: ”,偏移量是根據替換表示式構造的文字中的偏移量。例如,編譯 f’Bad {a b} field’ 會導致以下 args 屬性:(‘f-string: …’, (‘’, 1, 2, ‘(a b)n’, 1, 5))。

3.10 版中已更改: 添加了 end_linenoend_offset 屬性。

exception IndentationError

與不正確的縮排相關的語法錯誤的基類。這是 SyntaxError 的子類。

exception TabError

當縮排包含製表符和空格的不一致使用時引發。這是 IndentationError 的子類。

exception SystemError

當直譯器發現內部錯誤,但情況看起來不那麼嚴重以至於導致它放棄所有希望時引發。關聯值是一個字串,指示出了什麼問題(以低階術語表示)。在 CPython 中,這可能是由於不正確地使用了 Python 的 C API,例如返回一個 NULL 值而沒有設定異常。

如果您確信此異常不是您的錯,也不是您正在使用的包的錯,您應該向您的 Python 直譯器的作者或維護者報告。請務必報告 Python 直譯器的版本(sys.version;它也會在互動式 Python 會話開始時列印)、確切的錯誤訊息(異常的關聯值)以及如果可能的話,觸發錯誤的程式的來源。

exception SystemExit

此異常由 sys.exit() 函式引發。它繼承自 BaseException 而不是 Exception,這樣它就不會被捕獲 Exception 的程式碼意外捕獲。這使得異常能夠正確傳播並導致直譯器退出。當它未被處理時,Python 直譯器會退出;不列印堆疊回溯。建構函式接受與傳遞給 sys.exit() 相同的可選引數。如果值為整數,它指定系統退出狀態(傳遞給 C 的 exit() 函式);如果為 None,退出狀態為零;如果它具有其他型別(例如字串),則列印物件的值,退出狀態為一。

sys.exit() 的呼叫被轉換為異常,以便可以執行清理處理程式(try 語句的 finally 子句),並且偵錯程式可以在不冒失控風險的情況下執行指令碼。os._exit() 函式可以在絕對必要立即退出時使用(例如,在呼叫 os.fork() 後的子程序中)。

code

傳遞給建構函式的退出狀態或錯誤訊息。(預設為 None。)

exception TypeError

當操作或函式應用於不適當型別的物件時引發。關聯值是一個字串,提供有關型別不匹配的詳細資訊。

此異常可由使用者程式碼引發,以指示對物件的嘗試操作不受支援,並且不應受支援。如果物件應支援給定操作但尚未提供實現,則 NotImplementedError 是適當的引發異常。

傳遞錯誤型別的引數(例如,在期望 int 時傳遞 list)應導致 TypeError,但傳遞錯誤值的引數(例如,超出預期範圍的數字)應導致 ValueError

exception UnboundLocalError

當函式或方法中引用區域性變數,但該變數尚未繫結任何值時引發。這是 NameError 的子類。

exception UnicodeError

當發生與 Unicode 相關的編碼或解碼錯誤時引發。它是 ValueError 的子類。

UnicodeError 具有描述編碼或解碼錯誤的屬性。例如,err.object[err.start:err.end] 給出編解碼器失敗的特定無效輸入。

encoding

引發錯誤的編碼名稱。

reason

描述特定編解碼器錯誤的字串。

object

編解碼器嘗試編碼或解碼的物件。

start

object 中無效資料的第一個索引。

此值不應為負數,因為它被解釋為絕對偏移量,但此約束在執行時未強制執行。

end

object 中最後無效資料之後的索引。

此值不應為負數,因為它被解釋為絕對偏移量,但此約束在執行時未強制執行。

exception UnicodeEncodeError

在編碼期間發生 Unicode 相關錯誤時引發。它是 UnicodeError 的子類。

exception UnicodeDecodeError

在解碼期間發生 Unicode 相關錯誤時引發。它是 UnicodeError 的子類。

exception UnicodeTranslateError

在翻譯期間發生 Unicode 相關錯誤時引發。它是 UnicodeError 的子類。

exception ValueError

當操作或函式接收到一個型別正確但值不合適的引數時引發,並且情況未由更精確的異常(如 IndexError)描述。

exception ZeroDivisionError

當除法或模運算的第二個引數為零時引發。關聯值是一個字串,指示運算元的型別和操作。

以下異常是為了與以前版本相容而保留的;從 Python 3.3 開始,它們是 OSError 的別名。

exception EnvironmentError
exception IOError
exception WindowsError

僅在 Windows 上可用。

作業系統異常

以下異常是 OSError 的子類,它們根據系統錯誤程式碼引發。

exception BlockingIOError

當對設定為非阻塞操作的物件(例如套接字)進行操作時會阻塞時引發。對應於 errno EAGAIN, EALREADY, EWOULDBLOCKEINPROGRESS

除了 OSError 的屬性外,BlockingIOError 還可以有一個額外的屬性

characters_written

一個整數,包含在流阻塞之前寫入流的字元數。此屬性在使用 io 模組的緩衝 I/O 類時可用。

exception ChildProcessError

當對子程序的操作失敗時引發。對應於 errno ECHILD

exception ConnectionError

與連線相關問題的基類。

子類有 BrokenPipeErrorConnectionAbortedErrorConnectionRefusedErrorConnectionResetError

exception BrokenPipeError

ConnectionError 的子類,當嘗試寫入已關閉另一端的管道,或嘗試寫入已關閉寫入的套接字時引發。對應於 errno EPIPEESHUTDOWN

exception ConnectionAbortedError

ConnectionError 的子類,當連線嘗試被對等方中止時引發。對應於 errno ECONNABORTED

exception ConnectionRefusedError

ConnectionError 的子類,當連線嘗試被對等方拒絕時引發。對應於 errno ECONNREFUSED

exception ConnectionResetError

ConnectionError 的子類,當連線被對等方重置時引發。對應於 errno ECONNRESET

exception FileExistsError

當嘗試建立已存在的檔案或目錄時引發。對應於 errno EEXIST

exception FileNotFoundError

當請求的檔案或目錄不存在時引發。對應於 errno ENOENT

exception InterruptedError

當系統呼叫被傳入訊號中斷時引發。對應於 errno EINTR

3.5 版本中有所改變: Python 現在在系統呼叫被訊號中斷時會重試系統呼叫,除非訊號處理程式引發異常(詳情參見 PEP 475),而不是引發 InterruptedError

exception IsADirectoryError

當對目錄請求檔案操作(例如 os.remove())時引發。對應於 errno EISDIR

exception NotADirectoryError

當對非目錄的實體請求目錄操作(例如 os.listdir())時引發。在大多數 POSIX 平臺上,如果操作嘗試將非目錄檔案作為目錄開啟或遍歷,也可能引發此錯誤。對應於 errno ENOTDIR

exception PermissionError

嘗試執行沒有足夠訪問許可權的操作(例如檔案系統許可權)時引發。對應於 errno EACCESEPERMENOTCAPABLE

3.11.1 版本中有所改變: WASI 的 ENOTCAPABLE 現在對映到 PermissionError

exception ProcessLookupError

當給定程序不存在時引發。對應於 errno ESRCH

exception TimeoutError

當系統函式在系統級別超時時引發。對應於 errno ETIMEDOUT

3.3 版本新添: 以上所有 OSError 子類均已新增。

參見

PEP 3151 - 重新設計 OS 和 IO 異常層次結構

警告

以下異常用作警告類別;有關更多詳細資訊,請參見 警告類別 文件。

exception Warning

警告類別的基類。

exception UserWarning

由使用者程式碼生成的警告的基類。

exception DeprecationWarning

當警告旨在針對其他 Python 開發者時,用於警告已棄用功能的基類。

__main__ 模組外,預設警告過濾器會忽略此警告(PEP 565)。啟用 Python 開發模式 會顯示此警告。

棄用策略在 PEP 387 中描述。

exception PendingDeprecationWarning

關於過時且預期將來會棄用但目前尚未棄用的功能的警告的基類。

此類別很少使用,因為發出關於可能即將棄用的警告並不常見,對於已啟用的棄用,更傾向於使用 DeprecationWarning

預設警告過濾器會忽略此警告。啟用 Python 開發模式 會顯示此警告。

棄用策略在 PEP 387 中描述。

exception SyntaxWarning

關於可疑語法的警告的基類。

此警告通常在編譯 Python 原始碼時發出,在執行已編譯程式碼時通常不會報告。

exception RuntimeWarning

關於可疑執行時行為的警告的基類。

exception FutureWarning

當警告旨在針對使用 Python 編寫的應用程式的終端使用者時,用於警告已棄用功能的基類。

exception ImportWarning

關於模組匯入中可能存在的錯誤的警告的基類。

預設警告過濾器會忽略此警告。啟用 Python 開發模式 會顯示此警告。

exception UnicodeWarning

與 Unicode 相關的警告的基類。

exception EncodingWarning

與編碼相關的警告的基類。

有關詳細資訊,請參見 選擇性 EncodingWarning

在 3.10 版本加入。

exception BytesWarning

bytesbytearray 相關的警告的基類。

exception ResourceWarning

與資源使用相關的警告的基類。

預設警告過濾器會忽略此警告。啟用 Python 開發模式 會顯示此警告。

在 3.2 版本加入。

異常組

當需要引發多個不相關的異常時,使用以下內容。它們是異常層次結構的一部分,因此可以像所有其他異常一樣使用 except 進行處理。此外,它們被 except* 識別,它根據所包含異常的型別匹配它們的子組。

exception ExceptionGroup(msg, excs)
exception BaseExceptionGroup(msg, excs)

這兩種異常型別都包裝了序列 excs 中的異常。msg 引數必須是一個字串。兩種類之間的區別在於 BaseExceptionGroup 繼承自 BaseException,它可以包裝任何異常,而 ExceptionGroup 繼承自 Exception,並且只能包裝 Exception 的子類。這樣的設計是為了讓 except Exception 能捕獲 ExceptionGroup 但不能捕獲 BaseExceptionGroup

如果所有包含的異常都是 Exception 例項,則 BaseExceptionGroup 建構函式返回一個 ExceptionGroup 而不是 BaseExceptionGroup,因此可以用於自動選擇。另一方面,如果任何包含的異常不是 Exception 子類,則 ExceptionGroup 建構函式會引發 TypeError

message

建構函式中的 msg 引數。這是一個只讀屬性。

exceptions

建構函式中 excs 序列中的異常元組。這是一個只讀屬性。

subgroup(condition)

返回一個異常組,其中只包含當前組中符合 *condition* 的異常,如果結果為空則返回 None

條件可以是一個異常型別或異常型別的元組,在這種情況下,每個異常都使用與 except 子句中使用的相同檢查進行匹配。條件也可以是一個可呼叫物件(除了型別物件),它接受一個異常作為其唯一引數,併為應該在子組中的異常返回 True。

當前異常的巢狀結構在結果中保留,其 message__traceback____cause____context____notes__ 欄位的值也保留。空的巢狀組將從結果中省略。

將對巢狀異常組中的所有異常進行條件檢查,包括頂級異常和任何巢狀異常組。如果條件對於此類異常組為真,則將其完整包含在結果中。

3.13 版本新添: condition 可以是任何非型別物件的可呼叫物件。

split(condition)

類似於 subgroup(),但返回對 (match, rest),其中 matchsubgroup(condition)rest 是剩餘的不匹配部分。

derive(excs)

返回一個具有相同 message 的異常組,但它包裝了 excs 中的異常。

此方法由 subgroup()split() 使用,它們在各種上下文中用於分解異常組。子類需要重寫它,以便 subgroup()split() 返回子類的例項而不是 ExceptionGroup

subgroup()split() 將原始異常組的 __traceback____cause____context____notes__ 欄位複製到 derive() 返回的異常組中,因此這些欄位不需要由 derive() 更新。

>>> class MyGroup(ExceptionGroup):
...     def derive(self, excs):
...         return MyGroup(self.message, excs)
...
>>> e = MyGroup("eg", [ValueError(1), TypeError(2)])
>>> e.add_note("a note")
>>> e.__context__ = Exception("context")
>>> e.__cause__ = Exception("cause")
>>> try:
...    raise e
... except Exception as e:
...    exc = e
...
>>> match, rest = exc.split(ValueError)
>>> exc, exc.__context__, exc.__cause__, exc.__notes__
(MyGroup('eg', [ValueError(1), TypeError(2)]), Exception('context'), Exception('cause'), ['a note'])
>>> match, match.__context__, match.__cause__, match.__notes__
(MyGroup('eg', [ValueError(1)]), Exception('context'), Exception('cause'), ['a note'])
>>> rest, rest.__context__, rest.__cause__, rest.__notes__
(MyGroup('eg', [TypeError(2)]), Exception('context'), Exception('cause'), ['a note'])
>>> exc.__traceback__ is match.__traceback__ is rest.__traceback__
True

請注意,BaseExceptionGroup 定義了 __new__(),因此需要不同建構函式簽名的子類需要重寫該方法而不是 __init__()。例如,以下定義了一個異常組子類,它接受一個 exit_code 並從中構造組的訊息。

class Errors(ExceptionGroup):
   def __new__(cls, errors, exit_code):
      self = super().__new__(Errors, f"exit code: {exit_code}", errors)
      self.exit_code = exit_code
      return self

   def derive(self, excs):
      return Errors(excs, self.exit_code)

ExceptionGroup 一樣,任何同時是 Exception 子類的 BaseExceptionGroup 的子類只能包裝 Exception 的例項。

在 3.11 版本中新增。

異常層次結構

內建異常的類層次結構是

BaseException
 ├── BaseExceptionGroup
 ├── GeneratorExit
 ├── KeyboardInterrupt
 ├── SystemExit
 └── Exception
      ├── ArithmeticError
      │    ├── FloatingPointError
      │    ├── OverflowError
      │    └── ZeroDivisionError
      ├── AssertionError
      ├── AttributeError
      ├── BufferError
      ├── EOFError
      ├── ExceptionGroup [BaseExceptionGroup]
      ├── ImportError
      │    └── ModuleNotFoundError
      ├── LookupError
      │    ├── IndexError
      │    └── KeyError
      ├── MemoryError
      ├── NameError
      │    └── UnboundLocalError
      ├── OSError
      │    ├── BlockingIOError
      │    ├── ChildProcessError
      │    ├── ConnectionError
      │    │    ├── BrokenPipeError
      │    │    ├── ConnectionAbortedError
      │    │    ├── ConnectionRefusedError
      │    │    └── ConnectionResetError
      │    ├── FileExistsError
      │    ├── FileNotFoundError
      │    ├── InterruptedError
      │    ├── IsADirectoryError
      │    ├── NotADirectoryError
      │    ├── PermissionError
      │    ├── ProcessLookupError
      │    └── TimeoutError
      ├── ReferenceError
      ├── RuntimeError
      │    ├── NotImplementedError
      │    ├── PythonFinalizationError
      │    └── RecursionError
      ├── StopAsyncIteration
      ├── StopIteration
      ├── SyntaxError
      │    └── IndentationError
      │         └── TabError
      ├── SystemError
      ├── TypeError
      ├── ValueError
      │    └── UnicodeError
      │         ├── UnicodeDecodeError
      │         ├── UnicodeEncodeError
      │         └── UnicodeTranslateError
      └── Warning
           ├── BytesWarning
           ├── DeprecationWarning
           ├── EncodingWarning
           ├── FutureWarning
           ├── ImportWarning
           ├── PendingDeprecationWarning
           ├── ResourceWarning
           ├── RuntimeWarning
           ├── SyntaxWarning
           ├── UnicodeWarning
           └── UserWarning