內建的例外¶
在 Python 中,所有例外必須是從 BaseException
衍生的類別的實例。在陳述式 try
搭配 except
子句裡提到一個特定的類別時,那個子句也會處理任何從該類別衍生的例外類別(但不會處理該類別衍生自的例外類別)。兩個不是由子類別關係關聯起來的例外類別永遠不相等,就算它們有相同的名稱也是如此。
此章節裡列出的內建例外可以從直譯器或內建函式產生。除了特別提到的地方之外,它們會有一個關聯值表示錯誤發生的詳細原因。這可能是一個字串,或者是一些資訊項目組成的元組(例如一個錯誤代碼及一個解釋該代碼的字串)。這個關聯值通常當作引數傳遞給例外類別的建構函式。
使用者的程式碼可以引發內建例外。這可以用來測試例外處理器或者用來回報一個錯誤條件,就像直譯器會引發相同例外的情況;但需要注意的是沒有任何方式可以避免使用者的程式碼引發不適當的錯誤。
可以從內建的例外類別定義新的例外子類別;程式設計師被鼓勵從 Exception
類別或其子類別衍生新的例外,而不是從 BaseException
來衍生。更多關於定義例外的資訊可以在 Python 教學中的使用者自定的例外裡取得。
例外的情境¶
三個例外物件上的屬性提供關於引發此例外的情境的資訊:
- BaseException.__context__¶
- BaseException.__cause__¶
- BaseException.__suppress_context__¶
當引發一個新的例外而同時有另一個例外已經正在被處理時,這個新例外的
__context__
屬性會自動被設成那個已處理的例外。當使用except
或finally
子句或with
陳述式的時候例外會被處理。這個隱含的例外情境可以透過使用
from
搭配raise
來補充明確的原因:raise new_exc from original_exc
在
from
後面的運算式必須是一個例外或None
。它將會被設定成所引發例外的__cause__
。設定__cause__
也隱含地設定__suppress_context__
屬性為True
,因此使用raise new_exc from None
實際上會以新的例外取代舊的例外以利於顯示(例如轉換KeyError
為AttributeError
),同時保持舊的例外可以透過__context__
取得以方便 debug 的時候檢查。預設的回溯 (traceback) 顯示程式碼會顯示這些連鎖的例外 (chained exception) 加上例外本身的回溯。當存在的時候,在
__cause__
中明確地連鎖的例外總是會被顯示。而在__context__
中隱含地連鎖的例外只有當__cause__
是None
且__suppress_context__
是 false 時才會顯示。在任一種情況下,例外本身總是會顯示在任何連鎖例外的後面,因此回溯的最後一行總是顯示最後一個被引發的例外。
繼承自內建的例外¶
使用者的程式碼可以建立繼承自例外類型的子類別。建議一次只繼承一種例外類型以避免在基底類別之間如何處理 args
屬性的任何可能衝突,以及可能的記憶體佈局 (memory layout) 不相容。
CPython 實作細節: 為了效率,大部分的內建例外使用 C 來實作,參考 Objects/exceptions.c。一些例外有客製化的記憶體佈局,使其不可能建立一個繼承多種例外類型的子類別。類型的記憶體佈局是實作細節且可能會在不同 Python 版本間改變,造成未來新的衝突。因此,總之建議避免繼承多種例外類型。
基底類別 (base classes)¶
以下的例外大部分被用在當作其他例外的基底類別。
- exception BaseException¶
所有內建例外的基底類別。這不是為了讓使用者定義的類別直接繼承(可以使用
Exception
)。如果在這個類別的實例上呼叫str()
,會回傳實例的引數的表示,或者沒有引數的時候會回傳空字串。- with_traceback(tb)¶
此方法設定 tb 為該例外的新的回溯並回傳該例外物件。在 PEP 3134 的例外連鎖功能變得可用之前,此方法曾被更普遍使用。下面的範例顯示我們如何將
SomeException
的實例轉換為OtherException
的實例同時保留回溯。一旦被引發,目前的 frame 會被加進OtherException
的回溯,就像原來SomeException
的回溯會發生的一樣,我們允許它被傳遞給呼叫者:try: ... except SomeException: tb = sys.exception().__traceback__ raise OtherException(...).with_traceback(tb)
- __notes__¶
該例外的備註串列,使用
add_note()
來新增。此屬性在add_note()
被呼叫的時候建立。在 3.11 版新加入.
- exception Exception¶
所有內建、非系統退出 (non-system-exiting) 的例外都衍生自此類別。所有使用者定義的例外應該也要衍生自此類別。
- exception ArithmeticError¶
各種運算錯誤所引發的那些內建例外:
OverflowError
、ZeroDivisionError
、FloatingPointError
的基底類別。
- exception BufferError¶
當緩衝 (buffer) 相關的操作無法被執行時會引發此例外。
- exception LookupError¶
當使用在對映或序列上的鍵或索引是無效的時候所引發的例外:
IndexError
、KeyError
的基底類別。這可以被codecs.lookup()
直接引發。
實體例外¶
以下的例外是通常會被引發的例外。
- exception AttributeError¶
當屬性參照(參考 属性引用)或賦值失敗的時候被引發。(當物件根本不支援屬性參照或屬性賦值的時候,
TypeError
會被引發。)name
和obj
屬性可以使用建構函式的僅限關鍵字 (keyword-only) 引數來設定。當被設定的時候,它們分別代表被嘗試存取的屬性名稱以及被以該屬性存取的物件。在 3.10 版的變更: 新增
name
與obj
屬性。
- exception EOFError¶
當
input()
函式在沒有讀到任何資料而到達檔案結尾 (end-of-file, EOF) 條件的時候被引發。(注意:io.IOBase.read()
和io.IOBase.readline()
方法當達到 EOF 時會回傳空字串。)
- exception FloatingPointError¶
目前沒有被使用。
- exception GeneratorExit¶
當 generator 或 coroutine 被關閉的時候被引發;參考
generator.close()
和coroutine.close()
。此例外直接繼承自BaseException
而不是Exception
,因為技術上來說這不是一個錯誤。
- exception ImportError¶
當
import
陳述式嘗試載入模組遇到問題的時候會被引發。當from … import
裡的 “from list” 包含找不到的名稱時也會被引發。可選的僅限關鍵字引數 name 和 path 設定對應的屬性:
- name¶
嘗試引入 (import) 的模組名稱。
- path¶
觸發此例外的任何檔案的路徑。
- exception ModuleNotFoundError¶
ImportError
的子類別,當模組不能被定位的時候會被import
所引發。當在sys.modules
裡找到None
時也會被引發。在 3.6 版新加入.
- exception IndexError¶
當序列的索引超出範圍的時候會被引發。(切片索引 (slice indices) 會默默地被截短使其能落在允許的範圍內;如果索引不是整數,
TypeError
會被引發。)
- exception KeyError¶
當對映(字典)的鍵無法在已存在的鍵的集合中被找到時會被引發。
- exception KeyboardInterrupt¶
當使用者輸入中斷鍵 (interrupt key)(一般來說是 Control-C 或 Delete)時會被引發。在執行過程中,會定期檢查是否產生中斷。此例外繼承自
BaseException
以防止意外地被捕捉Exception
的程式碼所捕捉,而因此讓直譯器無法結束。備註
捕捉
KeyboardInterrupt
需要特殊的考量。因為它可以在無法預期的時間點被引發,可能在某些情況下讓正在跑的程式處在一個不一致的狀態。一般來說最好讓KeyboardInterrupt
越快結束程式越好,或者完全避免引發它。(參考 有关信号处理句柄和异常的注释。)
- exception MemoryError¶
當一個操作用光了記憶體但情況還可能被修復 (rescued)(透過刪除一些物件)的時候被引發。關聯的值是一個字串,表示什麼類型的(內部)操作用光了記憶體。需注意的是因為底層的記憶體管理架構(C 的
malloc()
函式),直譯器可能無法總是完整地從該情況中修復;僅管如此,它還是引發例外以讓堆疊回溯可以被印出,以防原因出在失控的程式。
- exception NameError¶
當找不到本地或全域的名稱時會被引發。這只應用在不合格的名稱 (unqualified name) 上。關聯的值是一個錯誤訊息,包含那個無法被找到的名稱。
name
屬性可以使用僅限關鍵字引數來設定到建構函式。當被設定的時候它代表被嘗試存取的變數名稱。在 3.10 版的變更: 新增
name
屬性。
- exception NotImplementedError¶
此异常派生自
RuntimeError
。 在用户自定义的基类中,抽象方法应当在其要求所派生类重写该方法,或是在其要求所开发的类提示具体实现尚待添加时引发此异常。備註
它不应当用来表示一个运算符或方法根本不能被支持 -- 在此情况下应当让特定运算符 / 方法保持未定义,或者在子类中将其设为
None
。備註
NotImplementedError
和NotImplemented
不能互换,尽管它们的名称和用途相似。有关何时使用的详细信息,请参阅NotImplemented
。
- exception OSError([arg])¶
- exception OSError(errno, strerror[, filename[, winerror[, filename2]]])
此异常在一个系统函数返回系统相关的错误时将被引发,此类错误包括 I/O 操作失败例如 "文件未找到" 或 "磁盘已满" 等(不包括非法参数类型或其他偶然性错误)。
构造器的第二种形式可设置如下所述的相应属性。 如果未指定这些属性则默认为
None
。 为了能向下兼容,如果传入了三个参数,则args
属性将仅包含由前两个构造器参数组成的 2 元组。构造器实际返回的往往是
OSError
的某个子类,如下文 OS exceptions 中所描述的。 具体的子类取决于最终的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 版的變更:
EnvironmentError
,IOError
,WindowsError
,socket.error
,select.error
与mmap.error
已被合并到OSError
,构造器可能返回其中一个子类。在 3.4 版的變更:
filename
属性现在是传给函数的原始文件名,而不是基于 filesystem encoding and error handler 进行编码或解码之后的名称。 此外,还添加了 filename2 构造器参数和属性。
- exception OverflowError¶
当算术运算的结果大到无法表示时将被引发。 这对整数来说不可能发生(宁可引发
MemoryError
也不会放弃尝试)。 但是出于历史原因,有时也会在整数超出要求范围的情况下引发 OverflowError。 因为在 C 中缺少对浮点异常处理的标准化,大多数浮点运算都不会做检查。
- exception RecursionError¶
此异常派生自
RuntimeError
。 它会在解释器检测发现超过最大递归深度 (参见sys.getrecursionlimit()
) 时被引发。在 3.5 版新加入: 在此之前将只引发
RuntimeError
。
- exception ReferenceError¶
此异常将在使用
weakref.proxy()
函数所创建的弱引用来访问该引用的某个已被作为垃圾回收的属性时被引发。 有关弱引用的更多信息请参阅weakref
模块。
- exception RuntimeError¶
当检测到一个不归属于任何其他类别的错误时将被引发。 关联的值是一个指明究竟发生了什么问题的字符串。
- exception StopIteration¶
由内置函数
next()
和 iterator 的__next__()
方法所引发,用来表示该迭代器不能产生下一项。当一个 generator 或 coroutine 函数返回时,将引发一个新的
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¶
必须由一个 asynchronous iterator 对象的
__anext__()
方法来引发以停止迭代操作。在 3.5 版新加入.
- exception SyntaxError(message, details)¶
当解析器遇到语法错误时引发。 这可以发生在
import
语句,对内置函数compile()
,exec()
或eval()
的调用,或是读取原始脚本或标准输入(也包括交互模式)的时候。异常实例的
str()
只返回错误消息。 错误详情为一个元组,其成员也可在单独的属性中分别获取。- 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_lineno
與end_offset
屬性。
- exception IndentationError¶
与不正确的缩进相关的语法错误的基类。 这是
SyntaxError
的一个子类。
- exception TabError¶
当缩进包含对制表符和空格符不一致的使用时将被引发。 这是
IndentationError
的一个子类。
- exception SystemError¶
当解释器发现内部错误,但情况看起来尚未严重到要放弃所有希望时将被引发。 关联的值是一个指明发生了什么问题的字符串(表示为低层级的符号)。
你应当将此问题报告给你所用 Python 解释器的作者或维护人员。 请确认报告 Python 解释器的版本号 (
sys.version
; 它也会在交互式 Python 会话开始时被打印出来),具体的错误消息(异常所关联的值)以及可能触发该错误的程序源码。
- exception SystemExit¶
此异常由
sys.exit()
函数引发。 它继承自BaseException
而不是Exception
以确保不会被处理Exception
的代码意外捕获。 这允许此异常正确地向上传播并导致解释器退出。 如果它未被处理,则 Python 解释器就将退出;不会打印任何栈回溯信息。 构造器接受的可选参数与传递给sys.exit()
的相同。 如果该值为一个整数,则它指明系统退出状态码(会传递给 C 的exit()
函数);如果该值为None
,则退出状态码为零;如果该值为其他类型(例如字符串),则会打印对象的值并将退出状态码设为一。对
sys.exit()
的调用会被转换为一个异常以便能执行清理处理程序 (try
语句的finally
子句),并且使得调试器可以执行一段脚本而不必冒失去控制的风险。 如果绝对确实地需要立即退出(例如在调用os.fork()
之后的子进程中)则可使用os._exit()
.- code¶
传给构造器的退出状态码或错误信息(默认为
None
。)
- exception TypeError¶
当一个操作或函数被应用于类型不适当的对象时将被引发。 关联的值是一个字符串,给出有关类型不匹配的详情。
此异常可以由用户代码引发,以表明尝试对某个对象进行的操作不受支持也不应当受支持。 如果某个对象应当支持给定的操作但尚未提供相应的实现,所要引发的适当异常应为
NotImplementedError
。传入参数的类型错误 (例如在要求
int
时却传入了list
) 应当导致TypeError
,但传入参数的值错误 (例如传入要求范围之外的数值) 则应当导致ValueError
。
- exception UnicodeError¶
当发生与 Unicode 相关的编码或解码错误时将被引发。 此异常是
ValueError
的一个子类。UnicodeError
具有一些描述编码或解码错误的属性。 例如err.object[err.start:err.end]
会给出导致编解码器失败的特定无效输入。- encoding¶
引发错误的编码名称。
- reason¶
描述特定编解码器错误的字符串。
- 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 中可用。
OS 异常¶
下列异常均为 OSError
的子类,它们将根据系统错误代码被引发。
- exception BlockingIOError¶
当一个操作将在设置为非阻塞操作的对象(例如套接字)上发生阻塞时将被引发。 对应于
errno
EAGAIN
,EALREADY
,EWOULDBLOCK
和EINPROGRESS
。除了
OSError
已有的属性,BlockingIOError
还有一个额外属性:
- exception ConnectionError¶
与连接相关问题的基类。
其子类有
BrokenPipeError
,ConnectionAbortedError
,ConnectionRefusedError
和ConnectionResetError
。
- exception BrokenPipeError¶
ConnectionError
的子类,当试图写入一个管道而其另一端已关闭,或者试图写入一个套接字而其已关闭写入时将被引发。 对应于errno
EPIPE
和ESHUTDOWN
。
- exception ConnectionAbortedError¶
ConnectionError
的子类,当一个连接尝试被对端中止时将被引发。 对应于errno
ECONNABORTED
。
- exception ConnectionRefusedError¶
ConnectionError
的子类,当一个连接尝试被对端拒绝时将被引发。 对应于errno
ECONNREFUSED
。
- exception ConnectionResetError¶
ConnectionError
的子类,当一个连接尝试被对端重置时将被引发。 对应于errno
ECONNRESET
。
- 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
EACCES
,EPERM
和ENOTCAPABLE
。在 3.11.1 版的變更: WASI 的
ENOTCAPABLE
现在被映射至PermissionError
。
在 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¶
与模糊的语法相关的警告的基类。
- exception RuntimeWarning¶
与模糊的运行时行为相关的警告的基类。
- exception FutureWarning¶
如果所发出的警告是针对以 Python 所编写应用的最终用户的,则以此作为与已弃用特性相关警告的基类。
- exception ImportWarning¶
与在模块导入中可能的错误相关的警告的基类。
会被默认警告过滤器忽略。 启用 Python 开发模式 时会显示此警告。
- exception UnicodeWarning¶
与 Unicode 相关的警告的基类。
- exception EncodingWarning¶
与编码格式相关的警告的基类。
細節請見 選擇性加入的編碼警告。
在 3.10 版新加入.
- 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
。BaseExceptionGroup
构造器返回一个ExceptionGroup
而不是BaseExceptionGroup
,如果所包含的全部异常都是Exception
的实例的话,因此它可以被用来制造自动化的选择。 在另一方面,ExceptionGroup
构造器则会引发TypeError
,如果所包含的任何异常不是Exception
的子类的话。- message¶
传给构造器的
msg
参数。 这是一个只读属性。
- exceptions¶
传给构造器的
excs
序列中的由异常组成的元组。 这是一个只读属性。
- subgroup(condition)¶
返回一个只包含来自当前组的匹配 condition 的异常的异常组,或者如果结果为空则返回
None
。condition 参数可以是一个接受异常并为应当纳入子分组的异常返回真值的函数,或者也可以是一个异常类型或一个由异常类型组成的元组,用来通过与
except
子句所用的相同检测来检测是否匹配。当前异常的嵌套结构会在结果中保留,就如其
message
,__traceback__
,__cause__
,__context__
和__notes__
字段的值一样。 空的嵌套组会在结果中被略去。条件检测会针对嵌套异常组中的所有异常执行,包括最高层级的和任何嵌套的异常组。 如果针对此类异常组的条件为真值,它将被完整包括在结果中。
- split(condition)¶
类似于
subgroup()
,但将返回(match, rest)
对,其中match
为subgroup(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
,任何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
│ └── 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