內建的例外

在 Python 中,所有例外必須是從BaseException 衍生的類別的實例。在陳述式try 搭配except 子句裡提到一個特定的類別時,那個子句也會處理任何從該類別衍生的例外類別(但不會處理該類別衍生自的例外類別)。兩個不是由子類別關係關聯起來的例外類別永遠不相等,就算它們有相同的名稱也是如此。

此章節裡列出的內建例外可以從直譯器或內建函式產生。除了特別提到的地方之外,它們會有一個關聯值表示錯誤發生的詳細原因。這可能是一個字串,或者是一些資訊項目組成的元組(例如一個錯誤代碼及一個解釋該代碼的字串)。這個關聯值通常當作引數傳遞給例外類別的建構函式。

使用者的程式碼可以引發內建例外。這可以用來測試例外處理器或者用來回報一個錯誤條件,就像直譯器會引發相同例外的情況;但需要注意的是沒有任何方式可以避免使用者的程式碼引發不適當的錯誤。

可以從內建的例外類別定義新的例外子類別;程式設計師被鼓勵從Exception 類別或其子類別衍生新的例外,而不是從BaseException 來衍生。更多關於定義例外的資訊可以在 Python 教學中的使用者自定的例外裡取得。

例外的情境

三個例外物件上的屬性提供關於引發此例外的情境的資訊:

BaseException.__context__
BaseException.__cause__
BaseException.__suppress_context__

當引發一個新的例外而同時有另一個例外已經正在被處理時,這個新例外的__context__ 屬性會自動被設成那個已處理的例外。當使用exceptfinally 子句或with 陳述式的時候例外會被處理。

這個隱含的例外情境可以透過使用from 搭配raise 來補充明確的原因:

raisenew_excfromoriginal_exc

from 後面的運算式必須是一個例外或None。它將會被設定成所引發例外的__cause__。設定__cause__ 也隱含地設定__suppress_context__ 屬性為True,因此使用raisenew_excfromNone 實際上會以新的例外取代舊的例外以利於顯示(例如轉換KeyErrorAttributeError),同時保持舊的例外可以透過__context__ 取得以方便 debug 的時候檢查。

預設的回溯 (traceback) 顯示程式碼會顯示這些連鎖的例外 (chained exception) 加上例外本身的回溯。當存在的時候,在__cause__ 中明確地連鎖的例外總是會被顯示。而在__context__ 中隱含地連鎖的例外只有當__cause__None__suppress_context__ 是 false 時才會顯示。

在任一種情況下,例外本身總是會顯示在任何連鎖例外的後面,因此回溯的最後一列總是顯示最後一個被引發的例外。

繼承自內建的例外

使用者的程式碼可以建立繼承自例外型別的子類別。建議一次只繼承一種例外型別以避免在基底類別之間如何處理args 屬性的任何可能衝突,以及可能的記憶體佈局 (memory layout) 不相容。

為了效率,大部分的內建例外使用 C 來實作,參考Objects/exceptions.c。一些例外有客製化的記憶體佈局,使其不可能建立一個繼承多種例外型別的子類別。型別的記憶體佈局是實作細節且可能會在不同 Python 版本間改變,造成未來新的衝突。因此,總之建議避免繼承多種例外型別。

基底類別 (base classes)

以下的例外大部分被用在當作其他例外的基底類別。

exceptionBaseException

所有內建例外的基底類別。這不是為了讓使用者定義的類別直接繼承(可以使用Exception)。如果在這個類別的實例上呼叫str(),會回傳實例的引數的表示,或者沒有引數的時候會回傳空字串。

args

提供給該例外建構函式的引數元組。一些內建的例外(像是OSError)預期接受特定數量的引數並賦予該元組的每一個元素一個特別的意義,其他例外則通常用一個提供錯誤訊息的單一字串來呼叫。

with_traceback(tb)

此方法設定tb 為該例外的新的回溯並回傳該例外物件。在PEP 3134 的例外連鎖功能變得可用之前,此方法曾被更普遍使用。下面的範例顯示我們如何將SomeException 的實例轉換為OtherException 的實例同時保留回溯。一旦被引發,目前的 frame 會被加進OtherException 的回溯,就像原來SomeException 的回溯會發生的一樣,我們允許它被傳遞給呼叫者:

try:...exceptSomeException:tb=sys.exception().__traceback__raiseOtherException(...).with_traceback(tb)
__traceback__

可寫入的欄位,儲存關聯到該例外的回溯物件。也可以參考raise 陳述式

add_note(note)

新增字串note 到例外的備註,在標準的回溯裡,備註出現在例外字串的後面。如果note 不是字串則引發TypeError

在 3.11 版被加入.

__notes__

該例外的備註串列,使用add_note() 來新增。此屬性在add_note() 被呼叫的時候建立。

在 3.11 版被加入.

exceptionException

所有內建、非系統退出 (non-system-exiting) 的例外都衍生自此類別。所有使用者定義的例外應該也要衍生自此類別。

exceptionArithmeticError

各種運算錯誤所引發的那些內建例外:OverflowErrorZeroDivisionErrorFloatingPointError 的基底類別。

exceptionBufferError

緩衝 (buffer) 相關的操作無法被執行時會引發此例外。

exceptionLookupError

當使用在對映或序列上的鍵或索引是無效的時候所引發的例外:IndexErrorKeyError 的基底類別。這可以被codecs.lookup() 直接引發。

實體例外

以下的例外是通常會被引發的例外。

exceptionAssertionError

assert 陳述式失敗的時候被引發。

exceptionAttributeError

當屬性參照(參考Attribute references)或賦值失敗的時候被引發。(當物件根本不支援屬性參照或屬性賦值的時候,TypeError 會被引發。)

nameobj 屬性可以使用建構函式的僅限關鍵字 (keyword-only) 引數來設定。當被設定的時候,它們分別代表被嘗試存取的屬性名稱以及被以該屬性存取的物件。

在 3.10 版的變更:新增nameobj 屬性。

exceptionEOFError

input() 函式在沒有讀到任何資料而到達檔案結尾 (end-of-file, EOF) 條件的時候被引發。(注意:io.IOBase.read()io.IOBase.readline() 方法當達到 EOF 時會回傳空字串。)

exceptionFloatingPointError

目前沒有被使用。

exceptionGeneratorExit

generatorcoroutine 被關閉的時候被引發;參考generator.close()coroutine.close()。此例外直接繼承自BaseException 而不是Exception,因為技術上來說這不是一個錯誤。

exceptionImportError

import 陳述式嘗試載入模組遇到問題的時候會被引發。當from...import 裡的 "from list" 包含找不到的名稱時也會被引發。

可選的僅限關鍵字引數namepath 設定對應的屬性:

name

嘗試引入 (import) 的模組名稱。

path

觸發此例外的任何檔案的路徑。

在 3.3 版的變更:新增namepath 屬性。

exceptionModuleNotFoundError

ImportError 的子類別,當模組不能被定位的時候會被import 所引發。當在sys.modules 裡找到None 時也會被引發。

在 3.6 版被加入.

exceptionIndexError

當序列的索引超出範圍的時候會被引發。(切片索引 (slice indices) 會默默地被截短使其能落在允許的範圍內;如果索引不是整數,TypeError 會被引發。)

exceptionKeyError

當對映(字典)的鍵無法在已存在的鍵的集合中被找到時會被引發。

exceptionKeyboardInterrupt

當使用者輸入中斷鍵 (interrupt key)(一般來說是Control-CDelete)時會被引發。在執行過程中,會定期檢查是否產生中斷。此例外繼承自BaseException 以防止意外地被捕捉Exception 的程式碼所捕捉,而因此讓直譯器無法結束。

備註

捕捉KeyboardInterrupt 需要特殊的考量。因為它可以在無法預期的時間點被引發,可能在某些情況下讓正在跑的程式處在一個不一致的狀態。一般來說最好讓KeyboardInterrupt 越快結束程式越好,或者完全避免引發它。(參考訊號處理程式與例外的說明。)

exceptionMemoryError

當一個操作用光了記憶體但情況還可能被修復 (rescued)(透過刪除一些物件)的時候被引發。關聯值是一個字串,表示什麼類型的(內部)操作用光了記憶體。需注意的是因為底層的記憶體管理架構(C 的malloc() 函式),直譯器可能無法總是完整地從該情況中修復;僅管如此,它還是引發例外以讓堆疊回溯可以被印出,以防原因出在失控的程式。

exceptionNameError

當找不到本地或全域的名稱時會被引發。這只應用在不合格的名稱 (unqualified name) 上。關聯值是一個錯誤訊息,包含那個無法被找到的名稱。

name 屬性可以使用僅限關鍵字引數來設定到建構函式。當被設定的時候它代表被嘗試存取的變數名稱。

在 3.10 版的變更:新增name 屬性。

exceptionNotImplementedError

此例外衍生自RuntimeError。在使用者定義的基礎類別裡,當抽象方法要求衍生類別覆寫該方法時應該要引發此例外,或者當類別正在開發中,可用此例外表示還需要加入真正的實作。

備註

此例外不應該用來表示根本沒有要支援的運算子或方法 ── 在這個情況下可以讓該運算子或方法保持未定義,或者如果是子類別的話將其設成None

警示

NotImplementedErrorNotImplemented 並不是可互換的。這個例外只能用在上面描述的情況;參考NotImplemented 裡關於內建常數正確使用方法的細節。

exceptionOSError([arg])
exceptionOSError(errno,strerror[,filename[,winerror[,filename2]]])

當系統函式回傳系統相關錯誤,包含像"找不到檔案"或"硬碟已滿"的 I/O 失敗會引發此例外(而非不合法的引數或其他次要的錯誤)。

建構函式的第二種形式會設定以下描述的相對應屬性。如果沒有給定則屬性預設為None。為了向後相容,如果傳入三個引數,args 屬性只會是包含建構函式前兩個引數的雙元素元組。

如同下面的作業系統例外所描述,實際上建構函式通常回傳OSError 的子類別。會依據最後errno 的值決定特定子類別。這個行為只發生在直接建構OSError 或透過別名,且產生子類別的時候不會被繼承。

errno

從 C 變數errno 而來的數值錯誤代碼。

winerror

在 Windows 下,這會提供你原生的 Windows 錯誤代碼。而errno 屬性是一個該原生錯誤代碼對於 POSIX 來說的近似翻譯。

在 Windows 下,如果建構函式引數winerror 是整數,則errno 屬性會根據該 Windows 錯誤代碼來決定,且errno 引數會被忽略。在其他平台上,winerror 引數會被忽略,而winerror 屬性會不存在。

strerror

作業系統提供的對應錯誤訊息。在 POSIX 下會使用 C 函式perror() 做格式化,而在 Windows 下會使用FormatMessage()

filename
filename2

對於包含檔案系統路徑的例外(像是open()os.unlink()),filename 是傳入函式的檔案名稱。對於包含兩個檔案系統路徑的函式(像是os.rename()),filename2 對應到傳入函式的第二個檔案名稱。

在 3.3 版的變更:EnvironmentErrorIOErrorWindowsErrorsocket.errorselect.errormmap.error 已合併進OSError,而建構函式可能會回傳子類別。

在 3.4 版的變更:filename 屬性現在是傳入函式的原始檔名,而不是從檔案系統編碼和錯誤處理函式編碼或解碼過的名稱。並且新增filename2 建構函式引數與屬性。

exceptionOverflowError

當運算操作的結果太大而無法表示的時候會引發此例外。這不會發生在整數上(會改成引發MemoryError 而不是放棄)。然而,因為一些歷史因素,OverflowError 有時候會因為整數在要求範圍之外而引發。因為在 C 裡面缺乏浮點數例外處理的標準化,大部分的浮點數運算都沒有被檢查。

exceptionPythonFinalizationError

此例外衍生自RuntimeError。當一個操作在直譯器關閉(也稱作Python 最終化 (Python finalization))期間被阻塞會引發此例外。

在 Python 最終化期間,能夠以PythonFinalizationError 被阻塞的操作範例:

也可以參閱sys.is_finalizing() 函式。

在 3.13 版被加入:在之前,會引發一般的RuntimeError

exceptionRecursionError

此例外衍生自RuntimeError。當直譯器偵測到超過最大的遞迴深度(參考sys.getrecursionlimit())時會引發此例外。

在 3.5 版被加入:在之前,會引發一般的RuntimeError

exceptionReferenceError

當一個被weakref.proxy() 函式建立的弱參照代理 (weak reference proxy) 被用來存取已經被垃圾回收 (garbage collected) 的參照物屬性時會引發此例外。更多關於弱參照的資訊參考weakref 模組。

exceptionRuntimeError

當偵測到一個不屬於任何其他種類的錯誤時會引發此例外。關聯值是一個表示確切什麼地方出錯的字串。

exceptionStopIteration

會被內建函式next()iterator__next__() 方法引發,用來表示疊代器沒有更多項目可以產生。

value

此例外物件有單一屬性value,當建構此例外時會以引數給定,預設為None

generatorcoroutine 函式回傳時,新的StopIteration 實例會被引發,而該函式的回傳值會被用來當作此例外建構函式的value 參數。

如果產生器程式直接或間接引發StopIteration,則其會被轉換成RuntimeError(保留StopIteration 作為新例外的成因)。

在 3.3 版的變更:新增value 屬性且產生器函式可以用它來回傳值。

在 3.5 版的變更:透過from__future__importgenerator_stop 引入 RuntimeError 的轉換,參考PEP 479

在 3.7 版的變更:預設對所有程式啟用PEP 479:在產生器引發的StopIteration 錯誤會轉換成RuntimeError

exceptionStopAsyncIteration

此例外必須被asynchronous iterator 物件的__anext__() 方法引發來停止疊代。

在 3.5 版被加入.

exceptionSyntaxError(message,details)

當剖析器遇到語法錯誤時會引發此例外。這可能發生在import 陳述式、在呼叫內建函式compile()exec()eval() 的時候,或者在讀取初始腳本或標準輸入(也包含互動式)的時候。

例外實例的str() 只回傳錯誤訊息。Details 是個元組,其成員也能夠以分開的屬性取得。

filename

發生語法錯誤所在的檔案名稱。

lineno

發生錯誤所在檔案的列號。這是以 1 開始的索引:檔案第一列的lineno 是 1。

offset

發生錯誤所在該列的欄號 (column)。這是以 1 開始的索引:該列第一個字元的offset 是 1。

text

涉及該錯誤的原始程式碼文字。

end_lineno

發生錯誤所在檔案的結束列號。這是以 1 開始的索引:檔案第一列的lineno 是 1。

end_offset

發生錯誤所在該結束列的欄號。這是以 1 開始的索引:該列第一個字元的offset 是 1。

對於發生在 f-string 欄位的錯誤,訊息會以 "f-string: " 為前綴,而偏移量 (offset) 是從替代表達式建構的文字的偏移量。例如編譯 f'Bad {a b} field' 會得到這個 args 屬性:('f-string: ...', ('', 1, 2, '(a b)n', 1, 5))。

在 3.10 版的變更:新增end_linenoend_offset 屬性。

exceptionIndentationError

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

exceptionTabError

當縮排包含製表符號 (tab) 和空白的不一致用法時會引發此例外。這是IndentationError 的子類別。

exceptionSystemError

當直譯器找到一個內部錯誤,但該情況看起來沒有嚴重到要讓它放棄所有的希望時會引發此例外。關聯值是一個表示什麼地方出錯的字串(以低階的方式表達)。在CPython 中,這可能是因為錯誤地使用 Python 的 C API,例如回傳一個NULL 值而沒有設定例外。

如果你確定這個例外不是你的或者所用套件的錯,你應該向你的 Python 直譯器作者或維護者回報此錯誤。務必要回報該 Python 直譯器的版本(sys.version;這也會在互動式 Python 會話的開頭被印出)、確切的錯誤訊息(該例外的關聯值)及如果可能的話,觸發此錯誤的程式來源。

exceptionSystemExit

此例外會被sys.exit() 函式引發。它繼承自BaseException 而不是Exception 因此不會被捕捉Exception 的程式意外地捕捉。這允許例外可以正確地向上傳遞並導致直譯器結束。當它未被處理時,Python 直譯器會結束;不會印出堆疊回溯。建構函式接受跟傳入sys.exit() 一樣的可選引數。如果該值是整數,它會指定系統的結束狀態(傳入 C 的exit() 函式 );如果它是None,結束狀態會是 0;如果它是其他型別(例如字串),則物件的值會被印出而結束狀態是 1。

sys.exit() 的呼叫會轉譯成例外讓負責清理的處理函式(try 陳述式的finally 子句)可以被執行,且讓除錯器可以在不冒著失去控制的風險下執行腳本。如果在絕對有必要立即結束的情況(例如在子行程呼叫完os.fork() 之後 )可以使用os._exit() 函式。

code

傳入建構函式的結束狀態或錯誤訊息。(預設是None。 )

exceptionTypeError

當一個操作或函式被用在不適合的型別的物件時會引發此例外。關聯值是一個字串,提供關於不相符型別的細節。

此例外可能被使用者程式碼引發,以表示並不支援物件上所嘗試的操作,且本來就無意這樣做。如果一個物件有意要支援某個給定的操作但尚未提供實作,該引發的正確例外是NotImplementedError

傳入錯誤型別的引數(例如當預期傳入int 卻傳入list)應該要導致TypeError,但傳入帶有錯誤值的引數(例如超出預期範圍的數值)應該要導致ValueError

exceptionUnboundLocalError

當在函式或方法裡引用某個區域變數,但該變數尚未被繫結到任何值的時候會引發此例外。這是NameError 的子類別。

exceptionUnicodeError

當 Unicode 相關的編碼或解碼錯誤發生時會引發此例外。這是ValueError 的子類別。

UnicodeError 有屬性描述編碼或解碼錯誤。例如err.object[err.start:err.end] 會提供讓編解碼器失敗的具體無效輸入。

encoding

引發錯誤的編碼名稱。

reason

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

object

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

start

object 中無效資料的開始索引。

end

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

exceptionUnicodeEncodeError

在編碼當中發生 Unicode 相關錯誤時會引發此例外。這是UnicodeError 的子類別。

exceptionUnicodeDecodeError

在解碼當中發生 Unicode 相關錯誤時會引發此例外。這是UnicodeError 的子類別。

exceptionUnicodeTranslateError

在轉譯當中發生 Unicode 相關錯誤時會引發此例外。這是UnicodeError 的子類別。

exceptionValueError

當一個操作或函式收到引數是正確型別但是不適合的值,且該情況無法被更精確的例外例如IndexError 所描述時會引發此例外。

exceptionZeroDivisionError

當除法或模數運算 (modulo operation) 的第二個引數是 0 的時候會引發此例外。關聯值是一個字串,表示運算元及運算的類型。

以下例外是為了相容於之前版本而保留;從 Python 3.3 開始,它們是OSError 的別名。

exceptionEnvironmentError
exceptionIOError
exceptionWindowsError

僅限於在 Windows 中使用。

作業系統例外

以下的例外是OSError 的子類別,它們根據系統錯誤代碼來引發。

exceptionBlockingIOError

當設置為非阻塞操作的物件(例如 socket)上的操作將要阻塞時會引發此例外。對應到errnoEAGAINEALREADYEWOULDBLOCKEINPROGRESS

除了OSError 的那些屬性之外,BlockingIOError 有多一個屬性:

characters_written

一個整數,內容為在其阻塞之前,已寫進串流的字元數。當使用io 模組裡的緩衝 I/O 類別時這個屬性是可用的。

exceptionChildProcessError

當子行程上的操作失敗時會引發此例外。對應到errnoECHILD

exceptionConnectionError

連線相關問題的基礎類別。

子類別有BrokenPipeErrorConnectionAbortedErrorConnectionRefusedErrorConnectionResetError

exceptionBrokenPipeError

ConnectionError 的子類別,當嘗試寫入管道 (pipe) 同時另一端已經被關閉時會引發此例外,或者當嘗試寫入已關閉寫入的 socket 時也會引發。對應到errnoEPIPEESHUTDOWN

exceptionConnectionAbortedError

ConnectionError 的子類別。當一個連線的嘗試被對等端點 (peer) 中斷時會引發此例外。對應到errnoECONNABORTED

exceptionConnectionRefusedError

ConnectionError 的子類別。當一個連線的嘗試被對等端點拒絕時會引發此例外。對應到errnoECONNREFUSED

exceptionConnectionResetError

ConnectionError 的子類別。當一個連線被對等端點重置時會引發此例外。對應到errnoECONNRESET

exceptionFileExistsError

當嘗試建立已存在的檔案或目錄時會引發此例外。對應到errnoEEXIST

exceptionFileNotFoundError

當請求不存在的檔案或目錄時會引發此例外。對應到errnoENOENT

exceptionInterruptedError

當系統呼叫被傳入的信號中斷時會引發此例外。對應到errnoEINTR

在 3.5 版的變更:現在當 syscall 被信號中斷時 Python 會重試系統呼叫而不會引發InterruptedError,除非信號處理器引發例外(理由可參考PEP 475)。

exceptionIsADirectoryError

當在目錄上請求檔案操作(例如os.remove())時會引發此例外。對應到errnoEISDIR

exceptionNotADirectoryError

當在某個不是目錄的東西上請求目錄操作(例如os.listdir())時會引發此例外。在大多數的 POSIX 平台上,如果嘗試操作開啟或遍歷一個當作目錄的非目錄檔案也會引發此例外。對應到errnoENOTDIR

exceptionPermissionError

當嘗試執行一個沒有合乎存取權限的操作時會引發此例外 — 例如檔案系統權限。對應到errnoEACCESEPERMENOTCAPABLE

在 3.11.1 版的變更:WASI 的ENOTCAPABLE 現在對應到PermissionError

exceptionProcessLookupError

當給定的行程不存在時會引發此例外。對應到errnoESRCH

exceptionTimeoutError

當系統函式在系統層級超時會引發此例外。對應到errnoETIMEDOUT

在 3.3 版被加入:加入以上所有的OSError 子類別。

也參考

PEP 3151 — 改寫作業系統與 IO 例外階層

警告

以下的例外是當作警告的種類使用;更多細節參考Warning Categories 文件。

exceptionWarning

警告種類的基礎類別。

exceptionUserWarning

使用者程式碼產生的警告的基礎類別。

exceptionDeprecationWarning

關於已棄用功能的警告的基礎類別,且當那些警告是針對其他 Python 開發者。

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

棄用原則描述在PEP 387 裡。

exceptionPendingDeprecationWarning

關於過時且預期未來要被棄用,但目前尚未被棄用的功能的警告的基礎類別。

因為發出關於可能即將被棄用的警告是不尋常的,此類別很少被使用,而對已經被棄用的情況會優先使用DeprecationWarning

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

棄用原則描述在PEP 387 裡。

exceptionSyntaxWarning

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

exceptionRuntimeWarning

關於可疑執行環境行為的警告的基礎類別。

exceptionFutureWarning

關於已棄用功能的警告的基礎類別,且當那些警告是針對以 Python 寫的應用程式的終端使用者。

exceptionImportWarning

關於在模組引入的可能錯誤的警告的基礎類別。

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

exceptionUnicodeWarning

Unicode 相關警告的基礎類別。

exceptionEncodingWarning

編碼相關警告的基礎類別。

細節參考選擇性加入的編碼警告

在 3.10 版被加入.

exceptionBytesWarning

bytesbytearray 相關警告的基礎類別。

exceptionResourceWarning

資源用法相關警告的基礎類別。

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

在 3.2 版被加入.

例外群組

當需要引發多個不相關例外時會使用下列的類別。它們是例外階層的一部分所以可以像所有其他例外一樣使用except 來處理。此外,它們會以包含的例外型別為基礎來比對其子群組而被except* 辨認出來。

exceptionExceptionGroup(msg,excs)
exceptionBaseExceptionGroup(msg,excs)

這兩個例外型別都將例外包裝在序列excs 中。msg 參數必須是字串。這兩個類別的差異是BaseExceptionGroup 擴充了BaseException 且可以包裝任何例外,而ExceptionGroup 擴充了Exception 且只能包裝Exception 的子類別。這個設計使得exceptException 可以捕捉ExceptionGroup 但不能捕捉BaseExceptionGroup

如果所有包含的例外都是Exception 實例,BaseExceptionGroup 建構函式會回傳ExceptionGroup 而不是BaseExceptionGroup,因此可以被使用來讓這樣的選擇自動化。另一方面來說,如果任何包含的例外不是Exception 的子類別,ExceptionGroup 建構函式會引發TypeError

message

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

exceptions

指定給建構函式excs 序列中的例外組成的元組。這是一個唯讀的屬性。

subgroup(condition)

回傳只包含從現有群組比對到condition 的例外的例外群組,或者當結果為空時回傳None

條件式可以是一個例外型別或是例外型別的元組,在此情況下,每個例外都會使用與except 子句中使用的相同檢查方法來檢查是否有匹配。條件式也可以是一個可呼叫物件(除了型別物件之外),其接受一個例外作為單一引數,而如果該例外應該在子群組中就回傳 true。

現有例外的巢狀結構會保留在結果裡,其message__traceback____cause____context____notes__ 欄位的值也一樣。空的巢狀群組會從結果裡排除。

條件會對巢狀例外群組裡的所有例外做檢查,包括頂層及任何巢狀的例外群組。如果條件對這樣的例外群組為 true,它會被完整包含在結果裡。

在 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() 更新。

>>>classMyGroup(ExceptionGroup):...defderive(self,excs):...returnMyGroup(self.message,excs)...>>>e=MyGroup("eg",[ValueError(1),TypeError(2)])>>>e.add_note("a note")>>>e.__context__=Exception("context")>>>e.__cause__=Exception("cause")>>>try:...raisee...exceptExceptionase:...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__ismatch.__traceback__isrest.__traceback__True

需注意BaseExceptionGroup 定義了__new__(),因此需要不同建構函式簽名的子類別需要覆寫它而不是__init__()。例如下面定義了一個例外群組子類別接受 exit_code 並從中建構群組的訊息。:

classErrors(ExceptionGroup):def__new__(cls,errors,exit_code):self=super().__new__(Errors,f"exit code:{exit_code}",errors)self.exit_code=exit_codereturnselfdefderive(self,excs):returnErrors(excs,self.exit_code)

ExceptionGroup 一樣,任何BaseExceptionGroup 的子類別且也是Exception 的子類別只能包裝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