第一招:读 traceback
Traceback (most recent call last):
File "app.py", line 12, in <module>
main()
File "app.py", line 8, in main
process(data)
File "app.py", line 4, in process
result = data["count"] / 0
ZeroDivisionError: division by zero
读 traceback 的顺序:
- 最后一行:错误类型 + 描述(这里是 ZeroDivisionError)
- 倒数最近的 File 行:错误发生的位置(app.py:4)
- 往上看:调用链——谁调谁导致到这一步
报错先看最后一行,看不懂再往上读。
第二招:print 调试(也叫"原始日志大法")
最快、最不需要工具:
def calc(x):
print(f"DEBUG: x = {x}") # 临时塞
result = x ** 2
print(f"DEBUG: result = {result}")
return result
Python 3.8+ 的 f"{x=}" 让这事更优雅:
print(f"{x=}") # x=42
print(f"{result=}") # result=1764
调完记得删——不然代码到处是 DEBUG。
第三招:breakpoint() — 内置断点
def calc(x):
breakpoint() # 跑到这就停
return x ** 2
跑 python app.py,会进入 pdb 交互:
> /path/to/app.py(2)calc()
-> return x ** 2
(Pdb)
常用命令:
| 命令 | 作用 |
|---|---|
n (next) |
执行下一行 |
s (step) |
步入函数 |
c (continue) |
继续到下一个断点 / 结束 |
l (list) |
显示当前位置代码 |
p x |
打印变量 |
pp x |
漂亮打印(pretty print) |
w (where) |
显示调用栈 |
u / d |
调用栈上下移动 |
q |
退出 |
第四招:IDE 调试器
VS Code / PyCharm 的图形化调试器最强:
- 鼠标点行号 = 设断点
- F5 启动调试
- 左侧面板看变量
- 鼠标悬停看任何表达式的值
- 条件断点("x > 10 时才停")
- 调用栈点击跳转
写大项目优先用 IDE 调试。
第五招:post-mortem(事后调试)
崩了之后进入崩溃现场:
python -m pdb app.py
或在代码里:
import sys
import pdb
def excepthook(t, v, tb):
pdb.post_mortem(tb)
sys.excepthook = excepthook
崩了不退出,自动进入 pdb——你可以查崩溃时所有变量。
第六招:rich 的 traceback
pip install rich
from rich.traceback import install
install(show_locals=True)
崩溃时彩色显示 traceback + 自动展开局部变量——比原版强 10 倍。
第七招:日志 + log_level
线上环境不方便加断点——靠日志:
logger.debug(f"输入: {x}")
result = expensive_calc(x)
logger.debug(f"输出: {result}")
平时 INFO 级别,有问题时改成 DEBUG,重跑或重启即可看到所有细节。
第八招:用最小复现
定位 bug 的终极武器:
- 把出问题的代码逐步精简
- 每次删一段,看还能不能复现
- 直到只剩 5 行还能复现 → bug 就在这 5 行里
这套方法 80% 的难题都能定位。
调试心态
"Don't guess. Verify."
不要靠猜。把每一步都打印出来 / 单步执行,直到亲眼看到错误发生的瞬间。
下一篇讲性能调优。