第 31 课 · 阶段五 · 文件与异常

异常处理 try / except

程序总会遇到意外:文件不存在、输入不是数字、除以 0。这一课学会用 try/except 优雅地兜住错误,而不是让程序直接崩溃。

第 31 课阶段五 · 文件与异常难度:进阶建议时长:35 分钟关键词:try · except · else · finally

🎯 学完本课你将掌握

  • 理解异常的概念与常见异常类型
  • 掌握 try/except/else/finally 四件套
  • 会用 raise 主动抛出异常

一、什么是异常

异常是程序运行时的错误事件。不处理时程序会中断并打印一大段红色的报错信息(traceback);用 try/except 可以捕获并从容处理。

二、最常见的几种异常

异常类型触发场景
ValueErrorint("abc") 转换失败
TypeError不同类型不兼容运算
ZeroDivisionError除以 0
IndexError索引越界
KeyError字典键不存在
FileNotFoundError文件不存在

三、基本用法

try except 基础.py
1try:
2 num = int(input("请输入一个数字:"))
3 print(100 / num)
4except ValueError:
5 print("输入的不是数字!")
6except ZeroDivisionError:
7 print("不能除以 0!")
8print("程序没有崩溃,继续执行")

四、捕获所有异常(不推荐单独使用)

多异常.py
1try:
2 x = 1 / 0
3except (ZeroDivisionError, TypeError) as e:
4 print("发生异常:", e) # 打印异常信息
5
6try:
7 risky()
8except Exception as e:
9 print("未知异常:", e) # 兜底捕获
⚠️ 注意
except Exception 能兜住几乎所有异常,但会掩盖真正的 Bug。正确做法:尽量捕获具体类型,最后再考虑通用兜底。

五、else 与 finally

else finally.py
1try:
2 n = int(input("数字:"))
3except ValueError:
4 print("输入无效")
5else:
6 print("没有异常,计算结果:", n * 2) # 仅在无异常时执行
7finally:
8 print("无论有没有异常,finally 都会执行")
✅ 要点
else:没异常才执行;finally:无论如何都执行(常用于关闭资源、写日志)。

六、主动抛出异常:raise

raise 用法.py
1def set_age(age):
2 if age < 0 or age > 150:
3 raise ValueError("年龄不合法:%d" % age)
4 return age
5
6try:
7 set_age(200)
8except ValueError as e:
9 print("捕获到:", e)

七、实战:健壮的文件读取

健壮读取.py
1filename = input("输入文件名:")
2try:
3 with open(filename, "r", encoding="utf-8") as f:
4 data = f.read()
5except FileNotFoundError:
6 print("文件不存在,请检查名字")
7except PermissionError:
8 print("没有权限读取该文件")
9except Exception as e:
10 print("其他错误:", e)
11else:
12 print("文件内容:", data[:100])

八、常见错误与解决

常见错误与解决

错误现象原因 / 解决方法
捕获了异常但没提示except 块里没写处理逻辑,至少要 print 或记日志。
finally 里的 return 覆盖了 try 的 returnfinally 一定会执行,别在里面写 return,会吞掉正常结果。
裸 except 被 PEP8 警告使用 except Exception 或具体异常类型。
✍️ 小练习
写一个除法函数 safe_div(a,b),内部捕获 ZeroDivisionError 并返回 "除数不能为0";再写一个程序让用户反复输入直到输入合法数字。
📌 本节小结
异常处理四件套:try 放风险代码、except 捕获处理、else 无异常才执行、finally 必执行。具体异常优先,raise 主动抛错。程序从此不再一碰就碎。