小白学 Python
AI 编程指南
© 2026 小白学 Python · 基于 walter201230/Python 教程
课程目录关于本站联系方式隐私政策GitHub

全部课程

  1. 00为什么学 Python
  2. 01Python 安装与第一个程序
  3. 02基本数据类型与变量
  4. 03List 与 Tuple
  5. 04Dict 与 Set
  6. 05条件与循环
  7. 06函数
  8. 07迭代
  9. 08面向对象
  10. 09模块
  11. 10魔法方法
  12. 11枚举类
  13. 12元类 metaclass
  14. 13线程与进程
  15. 14正则表达式
  16. 15闭包
  17. 16装饰器
  18. 17代码可读性
  19. 18pathlib:现代化路径处理
  20. 19异常处理
  21. 20dataclass
  22. 21上下文管理器(with)
  23. 22async / await
  24. 23pyproject.toml + uv
  25. 24ruff:一站式代码检查
  26. 25pytest:测试框架
  27. 26日志 logging
  28. 27打包发布到 PyPI
  29. 28学完之后
Python 环境加载中…

异常处理

5 道练习题·预计 100 分钟·做对一题解锁下一段

完整通读本章 →

教学 01 / 28· 已读

异常处理

写代码这件事,最让新手崩溃的瞬间是哪种?各位先别急着回答,我来描述一个场景:你刚学完语法,兴冲冲写了几十行代码,按下回车,结果终端弹出一坨红字:

文本
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    print(10 / 0)
ZeroDivisionError: division by zero

一脸懵。这玩意儿是啥?我哪里写错了?为啥程序就崩了?

其实啊,这就是 Python 的「异常机制」在工作。程序遇到了它处理不了的情况,比如除以零、读不存在的文件、把字符串当数字加,于是它就「抛」一个异常出来,然后整个程序停下来,告诉你:「我不干了,你来收拾」。

可是各位想想,真实世界里的程序怎么可能因为一个小问题就停摆?银行 ATM 你输错密码三次它会提示,不会直接死机;网页加载图片失败会显示一个占位图,不会整页白屏;微信收消息网络不通它会重试,不会闪退。这些场景背后,全都是「异常处理」在做事。

Python 早就给各位准备好了一整套工具:try / except / else / finally / raise / 自定义异常类,再加上 3.11 之后引入的「异常组」(ExceptionGroup)和 except*,整套机制非常完备。今天这篇,咱们就把这套机制从最朴素的写法一路捋到最新的 PEP 654,确保各位看完之后,再也不怕红字 traceback。

教学 02 / 28· 已读

程序为什么会「炸」

我们先从最简单的例子开始。打开 Python 解释器,敲一行:

Python· 预期报错示例
print(10 / 0)

输出:

文本
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

这就叫「异常」。Python 在执行 10 / 0 的时候发现:除数是零,这事儿数学上没法干,于是它创建了一个 ZeroDivisionError 对象,把这个对象「抛」出来。如果没人接,这个异常就会一路冒泡到最外层,最后由 Python 解释器接住,打印 traceback,然后退出程序。

各位再看一个:

Python· 预期报错示例
nums = [1, 2, 3]
print(nums[10])

输出:

文本
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
IndexError: list index out of range

IndexError,下标越界。再来一个:

Python· 预期报错示例
d = {'name': '两点水'}
print(d['age'])

输出:

文本
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyError: 'age'

KeyError,字典里没这个键。

各位发现了吧?每一种「错误」都有它自己的名字。这些名字就是异常的「类型」,是 Python 内置的一组类。它们不是给你看着玩的,是供你用来「精确捕捉」的——不同类型用不同的处理方式。

教学 03 / 28

最朴素的 try / except

来,我们把第一段代码改造一下。我们不希望除以零让整个程序崩溃,而是希望它在崩之前给出一句友好的提示,然后继续往下走:

Python· 可在网页运行
try:
    result = 10 / 0
    print(result)
except ZeroDivisionError:
    print('哎呀,除数不能是零')

print('程序继续运行')

输出:

文本
哎呀,除数不能是零
程序继续运行

是不是发现,红字 traceback 没了,程序也没崩,最后那句「程序继续运行」也乖乖打印出来了。

try / except 的语法就这么简单,记住三件事:

  • try: 块里放「可能出问题」的代码
  • except XxxError: 块里放「出了问题该怎么办」的代码
  • 如果 try 块没出错,except 块完全跳过,跟没写一样

各位再想想:如果 try 块里有十行代码,第三行炸了,后面七行还会执行吗?

答案是:不会。Python 一旦在 try 里发现异常,就立刻跳到对应的 except,try 里剩下的代码全部跳过。我们写个例子验证一下:

Python· 可在网页运行
try:
    print('第一行')
    print(10 / 0)
    print('第三行——这一行不会被执行')
except ZeroDivisionError:
    print('我接住了')

print('程序继续')

输出:

文本
第一行
我接住了
程序继续

果然,「第三行」没打印出来。这个细节非常重要,很多新手 debug 半天找不到问题,就是因为以为 try 里抛了异常之后下面还会跑——不会的,跳过了。

练习 1 / 5·safe_divide:用 try/except 处理除零题目有问题?

请写一个函数 safe_divide(a, b):

  • 正常情况下返回 a / b
  • 如果 b 是 0,捕获 ZeroDivisionError,打印 '除数不能是零',然后返回 None

然后调用:

Python
print(safe_divide(10, 2))
print(safe_divide(10, 0))

输出应该是:

文本
5.0
除数不能是零
None

注意 safe_divide(10, 0) 因为返回 None,外层 print 会打印 None。

main.py
可编辑
🔒做对当前题解锁下一段 ·0/5

推荐一个,全网最全最友好的中文 AI 编程指南: coding.stormzhang.ai

← 上一章18 · pathlib:现代化路径处理
异常处理
下一章 →20 · dataclass
本章目录

异常处理

  1. 教学 01异常处理
  2. 教学 02程序为什么会「炸」
  3. 教学 03最朴素的 try / except
  4. 练习 1safe_divide:用 try/except 处理除零
  5. 教学 04 🔒一次捕获多种异常
  6. 练习 2 🔒捕获 ValueError
  7. 教学 05 🔒拿到异常对象——`as e`
  8. 教学 06 🔒万能兜底——`except Exception`
  9. 教学 07 🔒异常的家族——继承层级
  10. 教学 08 🔒else——没出错的时候才走
  11. 教学 09 🔒finally——不管啥情况都得跑
  12. 练习 3 🔒finally:清理一定要跑
  13. 教学 10 🔒主动抛异常——`raise`
  14. 练习 4 🔒raise:主动抛异常
  15. 教学 11 🔒异常链——`raise ... from e`
  16. 教学 12 🔒自定义异常类
  17. 练习 5 🔒自定义异常:InvalidScoreError
  18. 教学 13 🔒内置异常速查表
  19. 教学 14 🔒一次想报告多个错误?——异常组(Python 3.11+)
  20. 教学 15 🔒用 `except*` 拆解异常组
  21. 教学 16 🔒add_note——给异常加备注(Python 3.11+)
  22. 教学 17 🔒小实战:safe_divide 与批量除法
  23. 教学 18 🔒嵌套的异常组——递归结构
  24. 教学 19 🔒`eg.subgroup` 与 `eg.split`——手动玩异常组
  25. 教学 20 🔒别犯这些反模式
  26. 教学 21 🔒assert——调试期的轻量级断言
  27. 教学 22 🔒traceback 模块——把错误打印得更友好
  28. 教学 23 🔒logging.exception——日志推荐写法
  29. 教学 24 🔒warnings——比异常温柔的提醒
  30. 教学 25 🔒try/except 在表达式里——不能写
  31. 教学 26 🔒EAFP vs LBYL——Python 的哲学
  32. 教学 27 🔒最后碎碎念几句
  33. 教学 28 🔒把错误缩小到一份输入

学习目录