内置异常

在 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