第七章异常处理与调试
在程序设计中,错误是无法完全避免的。用户可能输入了非法数据,文件可能丢失,网络可能断开,或者程序逻辑存在缺陷。如果程序没有妥善应对这些情况,系统就会在运行时中止执行并抛出错误信息。
为了让程序能够“遇错不崩”,Python 提供了完善的异常处理机制,使程序在错误发生后仍能有条不紊地继续执行或安全退出。
同时,利用调试技术,可以快速定位并修复问题,从而提升程序的稳定性与可靠性。
学习目标:
(1)理解异常(Exception)的概念,能区分语法错误与运行时错误。
(2)掌握 try 语句的完整结构及 raise 语句的用法。
(3)了解常见异常类型,并能针对不同错误进行分类处理。
(4)掌握 finally 的资源回收机制与自定义异常类的创建方法。
(5)学会使用调试工具与错误堆栈信息,快速定位和修复程序错误。
7.1 异常的概念与常见错误
在 Python 程序执行过程中,错误可分为两大类:语法错误与运行时异常。
• 语法错误(Syntax Error):代码结构本身不符合语法规则,解释器无法执行。
• 异常(Exception):语法正确,但在运行过程中出现了不可预料的问题,例如除数为 0 或访问了不存在的文件。
当 Python 检测到异常时,会立即停止当前代码块的执行,并向外层传递异常信息,这一过程称为“异常传播”(Exception Propagation)。如果没有任何代码捕获它,程序最终会崩溃并打印错误堆栈。
下表列出了程序运行中最常见的一些异常类型及其含义。
异常类型
含义说明
ZeroDivisionError
除数为零
ValueError
无法转换或非法的数值输入
TypeError
操作或函数应用到错误的类型上
IndexError
序列索引超出范围
KeyError
访问字典中不存在的键
FileNotFoundError
文件不存在
NameError
使用了未定义的变量
AttributeError
对象不存在该属性
OSError
操作系统相关错误(如文件读写失败)
例 7.1.1:常见错误示例
f = open("nofile.txt") # FileNotFoundError运行结果(部分):
FileNotFoundError: [Errno 2] No such file or directory: 'nofile.txt'程序遇到第一个未处理的异常就会立即终止。若想让程序在错误出现后继续执行,就必须通过异常捕获机制来“接住”这些错误。
7.2 try 语句语法
try 是 Python 中最核心的异常处理语句,用于检测、捕获并处理运行时错误。它由一个主块(try)和若干子句(except、else、finally)组成。
完整语法结构:
无论是否出错都执行的语句块语法说明:
• except 子句:捕获并处理指定类型的异常。
• except (异常类型1, 异常类型2) as e:在同一个 except 子句中可同时捕获多种异常类型。括号内为异常类的元组,匹配其中任意一种异常即会进入该分支。变量 e 用于接收异常对象,可通过 print(e) 查看具体错误信息。
• else 子句:仅在 try 块未发生异常时执行。
• finally 子句:始终执行,用于清理或释放资源。
使用说明:
• try 至少要搭配一个 except 或 finally。
• else 与 finally 都是可选的,但若同时存在,顺序必须为 except → else → finally。
• except 可设置多个分支,也可使用元组一次捕获多种异常。
• 异常匹配自上而下进行,遇到第一个匹配分支即停止。
• 避免使用裸 except:,推荐写为 except Exception: 或更具体的异常类型,以防误拦系统级异常。
• finally 子句总会执行,即使 try 块中出现 return、break、continue 或再次抛出异常。
7.3 try / except 捕获异常
try / except 是异常处理的基础结构,用于捕获并处理运行时错误。这是一种典型的“防御式编程”策略:提前预见可能出错的环节,并在异常发生时给出合适的处理措施。
基本语法结构:
处理异常的语句块执行过程说明:
• 当 try 块中的语句执行出错,Python 会立即跳转到对应的 except 块。
• 如果未发生异常,except 块将被跳过。
• 可设置多个 except 分支,以针对不同的异常类型做出不同反应。
例 7.3.1:除零错误处理
print("错误:除数不能为 0。")运行结果(示例):
错误:除数不能为 0。例 7.3.2:多种异常类型捕获
print("其他错误:", e)Exception 是所有异常的基类,可以捕获任意未被前面语句捕获的错误,常用于防止程序意外崩溃。
7.4 finally 与资源回收
在很多程序中,可能需要访问外部资源(如文件、网络、数据库等)。这些资源在使用完毕后,必须确保被及时关闭或释放,否则可能导致数据丢失或资源占用。
无论是否发生异常,finally 子句中的代码总会执行。常用于写入日志、关闭文件、断开连接等操作。
例 7.4.1:除法运算的资源清理
print("程序结束。")运行结果(示例):
程序结束。例 7.4.2:文件读取与关闭
print("文件已关闭。")运行结果(示例):
文件已关闭。通过 finally 子句确保文件始终能被关闭,即便读取失败,也不会造成资源泄露。
7.5 raise 与自定义异常
在实际开发中,我们有时需要使用 raise 语句在运行时显式触发异常对象,用来检测非法输入或违反业务逻辑的情况。这可以让程序更清晰地表达错误原因,也方便上层代码处理。
语法结构:
raise [异常类型 [(错误信息)]]语法说明:
• 异常类型通常是一个内置异常类(如 ValueError、TypeError),也可以是自定义异常类。
• 错误信息为可选项,用于说明异常原因。
• 若省略异常类型,则会重新抛出当前捕获的异常(用于嵌套异常处理)。
例 7.5.1:成绩验证
print("成绩合法:", score)运行结果(示例):
ValueError: 成绩必须在 0 到 100 之间!如果系统内置的异常类型无法准确表达程序逻辑错误,我们还可以通过继承 Exception 类来自定义异常类型。
例 7.5.2:自定义异常类
print("错误:", e)运行结果(示例):
错误: 不能对负数求平方根!自定义异常可以让代码在复杂项目中更具可读性,也更易于维护。
7.6 调试方法
异常可以帮助我们发现问题,而调试是解决问题的过程。调试(Debug)指的是找出程序错误根源并修复它的过程,是程序员的重要技能。
常见调试方式有:
• 调试法:输出关键变量值,查看逻辑执行情况。
• 模块:查看详细的错误堆栈信息。
• 断点调试:可逐行执行代码、观察变量变化与函数调用顺序。
例 7.6.1:traceback 获取错误信息
traceback.print_exc()运行结果(示例):
ZeroDivisionError: division by zerotraceback.print_exc() 能输出完整错误堆栈,帮助我们快速定位出错位置。
7.7 异常处理综合示例
通过综合应用前面的知识,我们可以让程序在复杂环境中更加健壮、安全。
例 7.7.1:文件读取与关闭(扩展版)
read_file("example.txt")例 7.7.2 模型预测输入检测
在 AI 应用中,输入数据的正确性直接决定了模型运行是否安全。本例模拟一个简单的文本分析模型,通过异常机制来防止非法输入。
print("AI 模型调用结束。")运行结果(示例):
AI 模型调用结束。在真实的人工智能系统中,输入检测与异常处理是模型安全运行的重要防线。
小结
本次课系统介绍了 Python 的异常处理与调试机制。通过合理运用 try、except、finally 与 raise 语句,程序能够在出现错误时保持稳定、安全的运行。这些机制构成了编写健壮程序的核心基础。
下次课将进入函数与模块化编程的学习,进一步探索如何构建更灵活、更结构化的程序体系。
“点赞有美意,赞赏是鼓励”
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.