📌 专栏:Python零基础全套入门教程
🎯 本章定位:从"程序报错崩溃"到"程序稳健容错"的核心章节。异常处理是项目上线必备技能,解决输入错误、文件不存在、网络失败等突发问题,让代码不再闪退、优雅容错,是进阶工程化代码的标志。
✅ 学习目标
-
理解错误与异常的区别,掌握程序报错原理
-
熟练掌握 try-except基础捕获异常语法
-
精通多异常捕获、万能异常、异常信息获取
-
掌握 else、finally 执行逻辑,学会资源释放
-
学会主动抛出异常 raise、自定义异常
-
掌握实战容错场景,规避异常处理高频坑点
一、异常是什么?
1.1 错误与异常区别
-
语法错误 :代码写错(少冒号、缩进错误、关键字写错),程序直接无法运行。
-
运行异常:代码语法没问题,运行时遇到意外情况,程序终止崩溃。
常见运行异常场景:
-
输入非数字,强制类型转换报错
-
除数为0运算报错
-
读取不存在的文件报错
-
字典取值key不存在、列表下标越界
-
网络请求超时、接口异常
异常处理的核心作用 :捕获运行错误,给出友好提示,避免程序整体崩溃退出,让程序稳健运行。
二、基础语法:try-except
2.1 完整语法结构
try:
# 可能出现异常的风险代码
风险逻辑
except 异常类型:
# 捕获到对应异常后执行的容错代码
容错处理
执行逻辑:
-
try 块代码无报错:正常执行,跳过 except
-
try 块代码报错:立刻终止当前try代码,跳转执行 except 容错逻辑
2.2 实战案例:解决输入数字报错
无异常处理(直接崩溃):
# 用户输入字母会直接程序报错
num = int(input("请输入数字:"))
print("数字翻倍:", num * 2)
加 try-except 容错(优雅处理):
try:
num = int(input("请输入数字:"))
print("数字翻倍:", num * 2)
except ValueError:
print("输入错误!请输入纯整数数字")
此时用户输入字母、符号,程序不会崩溃,只会提示友好文字。
三、常见具体异常类型(必记)
| 异常类型 | 触发场景 |
|---|---|
| ValueError | 数值类型错误(非数字转int/float失败) |
| ZeroDivisionError | 除数为0,除法运算报错 |
| IndexError | 列表、字符串下标越界 |
| KeyError | 字典访问不存在的键 |
| FileNotFoundError | 读取不存在的文件 |
| TypeError | 数据类型不匹配、运算类型错误 |
四、多异常捕获 + 异常信息打印
4.1 分别捕获不同异常
一段代码可能出现多种异常,可以写多个except分支,针对性处理。
try:
a = int(input("请输入被除数:"))
b = int(input("请输入除数:"))
res = a / b
print("结果:", res)
except ValueError:
print("输入错误:必须输入整数!")
except ZeroDivisionError:
print("运算错误:除数不能为0!")
4.2 获取异常详细信息(as e)
通过 as e 接收异常对象,打印系统原生报错信息,方便调试。
try:
1 / 0
except ZeroDivisionError as e:
print("捕获异常:", e)
print("异常类型:", type(e))
4.3 万能异常 Exception(开发常用)
不清楚具体异常类型时,使用 Exception 捕获所有常规异常,通用性极强。
try:
# 任意风险代码
num = int("abc")
except Exception as e:
print("程序出现异常:", e)
💡 建议:调试阶段优先精准捕获异常,上线项目可使用万能异常兜底,保证程序稳定。
五、else + finally 完整结构
完整异常处理四件套:try + except + else + finally
5.1 else 分支(无异常才执行)
try代码无报错、正常执行完毕,才会走else分支;出现异常则跳过else。
try:
num = int(input("请输入数字:"))
except Exception:
print("输入错误")
else:
print("输入正确,数字为:", num)
5.2 finally 分支(必执行,核心重点)
无论是否报错,finally代码一定会执行,常用于资源释放:关闭文件、关闭数据库连接、释放网络请求资源,杜绝资源泄露。
f = None
try:
f = open("test.txt", "r", encoding="utf-8")
content = f.read()
print(content)
except FileNotFoundError:
print("文件不存在")
finally:
# 无论读取成功失败,最终都关闭文件
if f:
f.close()
print("文件资源已释放")
💡 硬核知识点:即使try块中有return语句,finally依然会优先执行,是资源兜底的绝对保障。
六、主动抛出异常 raise
除了捕获系统异常,我们可以手动触发异常,用于数据校验、权限判断、参数合法性拦截。
6.1 基础抛出异常
def check_age(age):
if age < 0:
# 主动抛出数值异常
raise ValueError("年龄不能为负数!")
print("年龄校验通过")
check_age(-5)
6.2 结合try-except捕获主动异常
def check_score(score):
if score < 0 or score > 100:
raise ValueError("分数必须在0-100之间")
print("分数合法")
try:
check_score(120)
except ValueError as e:
print("参数错误:", e)
七、自定义异常(进阶实战)
系统内置异常无法满足业务场景时,可以自定义异常类,精准区分业务报错。
# 自定义异常类,继承Exception
class AgeError(Exception):
pass
def verify_age(age):
if age < 18:
raise AgeError("未满18岁,禁止访问")
try:
verify_age(16)
except AgeError as e:
print("业务拦截:", e)
except Exception as e:
print("其他异常:", e)
八、异常嵌套(复杂场景适配)
try语句支持嵌套,适配多层风险逻辑,分层容错处理。
try:
num = int(input("请输入数字:"))
try:
res = 100 / num
print("计算结果:", res)
except ZeroDivisionError:
print("内层捕获:除数不能为0")
except ValueError:
print("外层捕获:输入非数字")
九、高频易错点总结(面试+实战必看)
-
空except禁止使用:不写异常类型的except会捕获所有异常,隐藏bug,不利于调试,生产环境严禁使用。
-
捕获顺序:精准异常放前面,万能异常Exception放最后,否则精准异常永远无法触发。
-
else、finally位置:必须在所有except分支之后,语法顺序不能乱。
-
finally核心用途:只做资源关闭、清理操作,不写业务逻辑。
-
异常只会终止当前try块,不会崩溃整个程序,容错核心就是隔离错误。
-
不要滥用try-except:简单确定无风险的代码无需加异常捕获,避免代码臃肿。
十、本章实战习题(含标准答案)
基础习题
-
编写程序:接收用户输入整数,实现两数相除,捕获数值错误、除0错误,给出对应提示。
-
尝试读取 test.txt 文件,捕获文件不存在异常,使用finally确保文件关闭。
-
使用else实现:输入数字正确则打印数字平方,错误则提示输入异常。
进阶习题
-
定义函数,接收用户年龄,年龄大于150或小于0主动抛出异常,并用try捕获处理。
-
遍历列表
data = [10,20,"30",40],尝试全部转为整数,捕获转换异常并跳过错误元素。
思考题
- 自定义分数异常ScoreError,校验输入分数,超出0-100区间抛出自定义异常并捕获。
✅ 习题参考答案
# 1. 两数相除异常捕获
try:
a = int(input("请输入被除数:"))
b = int(input("请输入除数:"))
print("结果:", a / b)
except ValueError:
print("错误:请输入合法整数!")
except ZeroDivisionError:
print("错误:除数不能为0!")
# 2. 文件读取+finally资源释放
f = None
try:
f = open("test.txt", "r", encoding="utf-8")
print(f.read())
except FileNotFoundError:
print("文件不存在,读取失败")
finally:
if f:
f.close()
print("文件已关闭")
# 3. else分支实战
try:
num = int(input("请输入数字:"))
except Exception:
print("输入异常!")
else:
print("数字平方为:", num ** 2)
# 4. 主动抛异常
def check_age(age):
if age < 0 or age > 150:
raise ValueError("年龄数值不合法!")
print("年龄正常")
try:
check_age(200)
except ValueError as e:
print("校验失败:", e)
# 5. 遍历容错转换
data = [10,20,"30",40,"abc"]
new_list = []
for item in data:
try:
new_list.append(int(item))
except Exception:
continue
print("转换后列表:", new_list)
# 6. 自定义异常
class ScoreError(Exception):
pass
def check_score(score):
if not (0 <= score <= 100):
raise ScoreError("分数必须在0-100之间")
try:
check_score(105)
except ScoreError as e:
print("分数校验失败:", e)
十一、下期预告
本章节为Python零基础语法终章!至此,Python全套基础语法已全部学完。
💖 点赞 + 收藏 + 关注,零基础Python系统化学习圆满收官!