目录
1)最基本形态:try + except
运行会输出什么?
2)捕获“特定异常”:更推荐
3)拿到异常对象:看错误信息
4)多个 except:按顺序匹配
5)except 可以一次捕获一组异常
6)try + except + else:没出错才会走 else
7)try + finally:不管成败都执行(常用于资源释放)
8)完整形态:try / except / else / finally(记这个万能模板)
9)“报错时代码会输出什么?”——两种情况
情况 A:异常没被捕获(最常见的“红字大爆炸”)
情况 B:异常被捕获了(程序继续跑)
10)怎么“原样打印完整报错堆栈”?(调试神器)
11)raise:你也可以主动抛异常
12)异常体系的大树(你最需要认识的几层)
13)常见内置异常名称(按类别记忆)
语法/缩进(代码还没跑就挂)
类型和值(你传参传错了最常见)
数学与数值
索引/键查找
文件/系统/IO(统称 OSError 分支)
导入与模块
断言与运行时
迭代与生成器
14)几个实战建议(少踩坑)
我会先把 try/except 的语法形态讲清楚,再用一组可运行的小例子演示:无异常、捕获特定异常、多个 except、else、finally、raise、以及 traceback 输出在终端里长什么样。
下面把try / except讲透一点:它解决的问题就一句话——把“可能会炸”的代码包起来,炸了就按你写的策略处理;不炸就继续走。
1)最基本形态:try + except
try: x = 1 / 0 except: print("出错了,但我兜住了")运行会输出什么?
1/0会抛ZeroDivisionError被
except:捕获后,不会让程序崩溃,输出:
出错了,但我兜住了⚠️ 不建议裸写except:(会把几乎所有异常都吃掉,调试会很痛苦),后面说更推荐写法。
2)捕获“特定异常”:更推荐
try: x = 1 / 0 except ZeroDivisionError: print("除数不能为 0")输出:
除数不能为 0好处:只兜你预期的错误,别的错误照样暴露出来,方便定位。
3)拿到异常对象:看错误信息
try: int("abc") except ValueError as e: print("转换失败:", e)输出类似:
转换失败: invalid literal for int() with base 10: 'abc'as e让你能拿到异常对象,打印更具体的信息,或者写日志。
4)多个 except:按顺序匹配
try: x = int("abc") / 0 except ValueError: print("先处理 ValueError") except ZeroDivisionError: print("再处理 ZeroDivisionError")这里int("abc")先炸,所以输出:
先处理 ValueError要点:只会进入第一个匹配到的 except,后面的不会执行。
5)except 可以一次捕获一组异常
try: x = int("abc") / 0 except (ValueError, ZeroDivisionError) as e: print("捕获到:", type(e).__name__, e)输出类似:
捕获到: ValueError invalid literal for int() with base 10: 'abc'6)try + except + else:没出错才会走 else
try: x = 10 / 2 except ZeroDivisionError: print("除 0 了") else: print("没出错,结果是", x)输出:
没出错,结果是 5.0else很适合放“依赖 try 成功的后续逻辑”,让结构更清爽。
7)try + finally:不管成败都执行(常用于资源释放)
try: f = open("some.txt", "w") f.write("hello") finally: f.close() print("文件已关闭")无论中间是否异常,都会输出:
文件已关闭8)完整形态:try / except / else / finally(记这个万能模板)
try: ... except SomeError as e: ... else: ... finally: ...执行顺序规则(非常重要):
try 抛异常→ 进入匹配的
except→ 最后一定执行finallytry 不抛异常→ 跳过
except→ 执行else→ 最后一定执行finally
9)“报错时代码会输出什么?”——两种情况
情况 A:异常没被捕获(最常见的“红字大爆炸”)
比如:
x = 1 / 0 print("我会执行吗?")终端通常会输出Traceback(回溯),类似这样(格式大致一致,路径/行号会不同):
Traceback (most recent call last): File "demo.py", line 1, in <module> x = 1 / 0 ZeroDivisionError: division by zero并且程序直接终止,print("我会执行吗?")不会执行。
情况 B:异常被捕获了(程序继续跑)
try: x = 1 / 0 except ZeroDivisionError: print("我处理了这个错误") print("我还能继续运行")输出:
我处理了这个错误 我还能继续运行10)怎么“原样打印完整报错堆栈”?(调试神器)
有时候你想捕获异常同时把完整 traceback 打出来:
import traceback try: x = 1 / 0 except Exception: traceback.print_exc() # 打印完整堆栈 print("但程序没有崩")输出会包含那段Traceback ... ZeroDivisionError...,然后继续打印:
但程序没有崩11)raise:你也可以主动抛异常
def check_age(age): if age < 0: raise ValueError("age 不能为负数") return age try: check_age(-1) except ValueError as e: print("捕获到:", e)输出:
捕获到: age 不能为负数Python 里“异常名称”(也就是异常类)非常多,但它们有一棵清晰的继承树。先把骨架抓住,再记常见分支就够用了。
12)异常体系的大树(你最需要认识的几层)
BaseException(最顶层,几乎所有异常的祖宗)
SystemExit:
sys.exit()触发,程序准备退出(一般别乱抓)KeyboardInterrupt:你按
Ctrl+C触发(一般别吞掉)GeneratorExit:生成器关闭相关
Exception:我们日常业务代码通常捕获的都是它的子类
所以你经常会看到建议写:
try: ... except Exception as e: ...而不是except BaseException(因为后者会把 Ctrl+C、退出信号也吞了,容易“关不掉程序”)。
13)常见内置异常名称(按类别记忆)
下面这些是日常最常见的(远比死记全部更实用):
语法/缩进(代码还没跑就挂)
SyntaxError:语法错误
IndentationError/TabError:缩进/Tab 混用问题
类型和值(你传参传错了最常见)
TypeError:类型不对(比如把字符串当函数调用、把
None当可迭代)ValueError:类型对,但值不合法(重点后面讲)
AttributeError:对象没有这个属性/方法(
obj.xxx不存在)NameError:变量名没定义
UnboundLocalError:局部变量引用前未赋值(NameError 的子类)
数学与数值
ZeroDivisionError:除以 0
OverflowError:数值溢出(少见,但有)
FloatingPointError:浮点错误(通常需特定设置才会显现)
ArithmeticError:算术错误的父类(一般不直接抛)
索引/键查找
IndexError:下标越界(list/tuple)
KeyError:字典 key 不存在
LookupError:IndexError/KeyError 的父类
文件/系统/IO(统称 OSError 分支)
FileNotFoundError:文件不存在
PermissionError:权限不足
IsADirectoryError/NotADirectoryError
TimeoutError:超时
OSError:上面这些的父类(系统调用失败大多归这类)
导入与模块
ImportError:导入失败
ModuleNotFoundError:模块找不到(ImportError 子类)
断言与运行时
AssertionError:
assert失败RuntimeError:运行时错误(很多库爱用它兜底,比如 PyTorch 常见)
NotImplementedError:方法未实现(常用于抽象基类/占位)
迭代与生成器
StopIteration:迭代结束(for 循环内部会处理掉,你一般见不到)
StopAsyncIteration:异步迭代结束
14)几个实战建议(少踩坑)
✅优先捕获具体异常:
except ValueError:比except:更健康✅不要用 try 包太大块代码:范围越小,越容易定位是谁炸了
✅需要清理资源用 finally 或 with(文件/锁/连接)
⚠️
except Exception会捕获大部分“普通异常”,但不会捕获像KeyboardInterrupt/SystemExit这类“系统级退出信号”(通常也不该捕获)