第 36 章 使用例外情况进行设计 使用例外情况进行设计
本作品已使用人工智能进行翻译。欢迎您提供反馈和意见:translation-feedback@oreilly.com
本章通过收集异常设计主题和常见用例示例,以及本部分的疑难问题和练习,为本书的部分画上了圆满的句号。由于本章也是本书基础知识部分的收尾部分,因此也包含了对开发工具的简要概述,以帮助你从 Python 初学者向 Python 应用程序开发者过渡。
嵌套异常处理程序
迄今为止,我们的大多数示例 都只使用了一个try 来捕获异常,但如果一个try 物理上嵌套在另一个里面,会发生什么情况呢?那么,如果一个try 调用运行另一个try 的函数又是什么意思呢?从技术上讲,无论是从语法还是从代码的运行控制流来看,try 语句都可以嵌套。我曾简单提到过这一点,但我们还是要在这里澄清一下这个概念。
如果您意识到 Python 在运行时会堆叠 try语句,那么这两种情况都可以理解。当出现异常时,Python 返回到最近输入的带有匹配except 子句的try 语句。因为每个try 语句都会留下一个标记,所以 Python 可以通过检查堆叠的标记跳回到更早的trys。这种活动处理程序的嵌套就是我们所说的将异常传播到 "更高 "处理程序的意思--这些处理程序就是在程序执行流中较早输入的try语句。
图 36-1展示了当带有except 子句的try语句在运行时嵌套时发生的情况。进入try 块的代码量可能很大,它可能包含调用函数,调用函数会调用其他代码来观察相同的异常。当异常最终产生时,Python 会跳回最近进入的命名该异常的try 语句,运行该语句的except 子句,然后在该try 之后恢复执行。

图 36-1. 嵌套的 try/except 语句:当异常发生时(由您或 Python 引起),控制权跳回到最近输入的带有匹配 except 子句的 try 语句,程序在该 try 语句之后继续运行。except 子句拦截并停止异常--它们是您处理异常并从异常中恢复的地方。
一旦异常被捕获,它的生命就结束了--控制权不会跳回到命名异常的所有匹配try;只有第一个(即最近的)处理程序才有机会处理它。例如,在图 36-1 中,函数func2 中的raise 语句将控制权送回func1 中的处理程序,然后程序在func1 中继续运行。
相比之下,当只包含finally 子句的try 语句被嵌套时,当异常发生时,会依次运行每个 finally 块--Python 会继续将异常向上传播到其他try,最终可能会传播到顶层默认处理程序(标准错误信息打印机)。如图 36-2所示,finally 子句并不会杀死异常--它们只是指定了在异常传播过程中,在每个try 出来时要运行的代码。如果有多个try/finally 子句在异常发生时处于活动状态,那么所有子句都将运行,除非try/except在运行过程中捕获了异常。

图 36-2. 嵌套的 try/finally 语句:当这里出现异常时,控制返回到最近输入的 try,运行其 finally 语句,但随后异常会继续传播到所有活动 ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access