什么是异常
异常是指 程序运行过程中出现的错误。
当 Python 在执行代码时检测到错误,会:
- 中止程序运行
- 输出错误提示(也称 BUG)
例如 PDF 第 1 页的示例代码:
f = open("C:/code/观止.txt", "r")
如果文件不存在,程序会报错并停止。
PDF 图片中的错误提示(文字化)
PDF 第 1 页展示的错误信息:
Traceback (most recent call last):
File "C:\code\pythonDemo\test_02.py", line 3, in <module>
f = open("C:/code/观止.txt", "r")
FileNotFoundError: [Errno 2] No such file or directory: 'C:/code/观止.txt'
Process finished with exit code 1
说明:
- FileNotFoundError 是异常类型
- 程序无法继续执行并停止退出
异常的定义总结
异常 = 程序运行中检测到错误 → 程序中断 + 错误提示。
为什么要捕获异常
程序运行过程中,如果出现错误,又没有进行异常处理,程序会直接崩溃并停止运行。
但在真实项目中,一个小错误导致整个程序终止,是不可接受的。
捕获异常的目的
避免程序崩溃
异常处理可以让程序:
- 不因为一个错误就中断
- 继续往下执行其他逻辑
换句话说:
捕获异常 = 让程序更稳定、更健壮。
对错误进行友好提示
而不是让程序直接报一堆用户看不懂的英文红字(如 PDF 页面的 FileNotFoundError 报错)。
例如:
如果读取文件失败,我们可以提示:
文件不存在,已自动为你创建。
给错误提供“后备方案”
举例(PDF 第 1 页示例思想文字化):
- 尝试使用
"r"模式读取文件,如果失败(文件不存在) - 自动使用
"w"模式创建文件 - 程序继续执行,不受影响
总结一句话
捕获异常的意义就是:让程序遇到错误时不崩溃,并能优雅地处理问题,继续运行。
如何捕获异常
当程序中有可能发生错误时,我们需要提前做好准备,让程序在出现异常时能够继续运行,而不是直接崩溃。
Python 中使用 try + except 结构进行异常捕获。
捕获常规异常
这是最基础、最常用的异常捕获方式。
基本语法
try:
可能发生错误的代码
except:
出现异常后要执行的代码
行为说明:
- 无错误 → try 中全部代码正常执行,except 不执行
- 有错误 → try 只执行到出错的那一行,会立刻跳到 except
- except 块负责处理错误,让程序不中断继续运行
PDF 示例(已文字化)
第一次运行,文件不存在:
try:
print("r模式打开")
f = open("C:/code/观止.txt", "r") # 报错
print("r模式打开") # 不执行
except:
print("w模式打开")
f = open("C:/code/观止.txt", "w") # 自动创建文件
print("w模式打开")
输出(来自 PDF 截图内容):
r模式打开
w模式打开
第二次运行(文件已存在,不再报错):
r模式打开
r模式打开
捕获特定异常
可只捕获某一种异常,而不是捕获所有异常。
基本语法
try:
可能发生错误的代码
except 异常类型 as e:
错误处理代码
示例:捕获未定义变量 NameError
try:
print(name) # name 未定义 → 报错
except NameError as e:
print("name变量名称未定义错误")
输出(PDF 内容):
name变量名称未定义错误
若异常类型不匹配,将无法捕获。
捕获多个异常
两种方式:
方式一:捕获所有异常(Exception)
与 except: 类似,但更规范:
try:
f = open("C:/code/study.txt", "r")
except Exception as e:
print("文件不存在")
方式二:捕获指定类型组成的元组
try:
f = open("C:/code/study.txt", "r")
except (FileNotFoundError, NameError) as e:
print("文件不存在")
示例 2:
try:
print(name)
except (FileNotFoundError, NameError) as e:
print("名称未定义")
PDF 图示提示:
未包含在元组中的异常类型不会被捕获。
打印异常信息
异常对象 e 中包含错误描述,可以输出查看:
try:
print(num) # num 未定义
except (NameError, ZeroDivisionError) as e:
print(e)
输出(PDF 截图文字化):
name 'num' is not defined
异常 else
else 表示:如果没有异常,执行 else 中的代码。
示例(来自 PDF page 4):
try:
print("正常")
except (NameError, ZeroDivisionError) as e:
print(e)
else:
print("无异常")
输出:
正常
无异常
若 try 中发生异常,则 else 不执行。
异常 finally
finally 表示:无论是否异常,都会执行的代码。
通常用来确保资源释放,比如关闭文件。
示例(PDF page 5):
global f
try:
f = open("C:/code/aaa.txt", "r")
except Exception as e:
print(e)
finally:
f.close() # 无论如何都会执行
好处:
- 即使 try 里出错,文件也会被 close,不会出现“文件被占用”的情况。
异常的传递
异常是具有 传递性(沿调用链向外抛出) 的。
也就是说,当一个函数中发生了异常,而它内部没有进行捕获,那么这个异常会向上一级函数传递;如果仍然没有被捕获,则继续向上一级传递,直到传递到主函数(main)。
如果整个调用链都没有捕获该异常,程序最终会报错并终止运行。
异常传递机制说明
PDF 第 6 页中的图示(完整文字化如下):
示例代码结构:
def func01():
print("这是func01开始")
num = 1 / 0 # 此处产生 ZeroDivisionError
print("这是func01结束")
def func02():
print("这是func02开始")
func01() # 调用 func01
print("这是func02结束")
def main():
try:
func02() # 调用 func02
except Exception as e:
print(e)
main()
图示说明(来自 PDF 流程图文字化)
- func01 中出现异常(1 / 0),但 func01 没有捕获异常
→ 异常向上抛给调用者 func02 - func02 中也没有捕获异常
→ 异常继续向上抛给 main - main 中使用 try…except 捕获所有异常
→ 异常最终被 main 捕获处理
→ 程序不会崩溃
运行结果(PDF 内容文字化)
输出:
这是func02开始
这是func01开始
division by zero
解释:
- func01 开始输出,但异常发生后不再继续执行
- 异常被一路传递到 main
- main 捕获异常并打印错误信息:
division by zero - 程序未崩溃,优雅结束
为什么要利用异常传递?
PDF 第 6 页解释如下:
- 可以在 主函数统一处理所有异常
- 无论程序中哪个位置发生异常,都能集中捕获并处理
- 让程序结构更清晰,不需要在每个小函数中写 try/except
- 提升代码可维护性
一句话总结:
异常会沿调用链向外抛出,直到被某一层捕获。统一在顶层处理异常,是大型程序的常用方式。
Python 异常处理总结
本章的核心思想:
让程序面对错误时 不崩溃、能处理、有方案、能继续运行。
以下是思维导图内容的完整文字版,涵盖异常本质、作用、捕获方式、异常链传递等知识。
什么是异常
- 程序运行过程中出现的错误称为异常
- 异常会导致程序中断并输出报错信息(BUG)
- 常见异常如:文件不存在、变量未定义、除零错误等
异常示例:
FileNotFoundError: No such file or directory
NameError: name 'xxx' is not defined
ZeroDivisionError: division by zero
为什么要捕获异常
- 避免程序因为一个小错误而整个崩溃
- 提供友好提示,让程序更加健壮
- 为错误提供备用方案(如文件不存在 → 自动创建)
- 提升项目级应用的稳定性
一句话总结:
捕获异常 = 优雅处理错误,不让程序崩溃。
如何捕获异常
Python 使用 try…except 系列语法:
try + except(常规异常)
try:
可能出错的代码
except:
错误处理代码
特点:
- except 能捕获所有异常
- 出现异常后 try 块立即中断并跳到 except
捕获特定异常
try:
代码
except 异常类型 as e:
错误处理
常用异常类型:
- FileNotFoundError
- NameError
- ZeroDivisionError
- ValueError
- TypeError 等
捕获多个异常
方式 1:捕获所有异常(Exception)
except Exception as e:
方式 2:捕获多个指定异常
except (TypeError, ValueError) as e:
打印异常信息
except Exception as e:
print(e)
e 中包含异常原因,可用于日志记录、调试等。
异常 else
try:
代码
except:
异常时执行
else:
无异常时执行
except 触发 → else 不执行
无异常 → else 执行
异常 finally
try:
代码
except:
错误处理
finally:
无论是否异常都会执行
常用于:
- 关闭文件
- 释放数据库连接
- 释放系统资源
异常的传递(调用链中的传播)
异常会沿着函数调用链向外抛:
func1 → func2 → main
若 func1 出现异常:
- func1 未捕获 → 抛给 func2
- func2 未捕获 → 抛给 main
- main 捕获 → 程序不会崩溃
优点:
- 可以在主函数统一处理所有异常
- 不需要在每个函数内都写 try/except
- 让程序结构更清晰
异常处理整体流程总结
try:
正常逻辑
except:
处理异常(备用方案)
else:
正常逻辑执行成功时运行
finally:
是否异常都要执行(资源释放)
一句话总结异常处理体系
- 捕获异常,让程序不崩溃
- 选择性捕获想处理的异常类型
- else 处理无异常逻辑
- finally 做资源清理
- 异常会沿调用链逐级向外抛
- 顶层统一异常捕获是大型项目标准做法