5.0 KiB
doc_type, full_text
| doc_type | full_text |
|---|---|
| short | sources/03_Debugging.md |
03_Debugging 总结
本文讲解 Python 程序崩溃后的基础调试方法,重点包括如何阅读 traceback、使用交互式解释器保留现场、用 print() 辅助排查,以及通过 Python 内置调试器 pdb 进行断点调试。
核心内容
1. 从 traceback 开始定位错误
当 Python 程序崩溃时,会输出 traceback,展示函数调用链和最终异常原因。
关键原则:
- traceback 的最后一行通常是崩溃的直接原因。
- 上方的
File ... line ... in ...展示了调用栈,即程序如何一步步走到出错位置。 - 错误类型和错误信息非常重要,例如:
AttributeError: 'int' object has no attribute 'append'- 表示代码试图在整数对象上调用
append()方法。
文中建议:如果 traceback 难以理解,可以把完整 traceback 粘贴到搜索引擎中查找相关解释。
相关概念:debugging、traceback、exceptions
2. 使用 python3 -i 保留崩溃现场
运行脚本时加上 -i 选项:
python3 -i blah.py
如果程序崩溃,Python 不会立即退出,而是进入交互式 REPL:
>>>
这样可以在崩溃后继续检查解释器状态,例如:
- 查看变量值
- 调用函数
- 检查对象类型
- 复现局部问题
这种方式适合快速探索程序崩溃时的环境,是一种轻量级调试技巧。
相关概念:repl、debugging、runtime state
3. 使用 print() 调试
print() 调试是一种常见且实用的排查方式,通过在代码中输出变量和执行路径来理解程序行为。
本文特别强调:调试输出时应优先使用 repr():
def spam(x):
print('DEBUG:', repr(x))
原因是:
print(x)输出的是面向用户的友好显示。repr(x)输出的是更精确、面向开发者的表示形式。
示例:
>>> from decimal import Decimal
>>> x = Decimal('3.4')
>>> print(x)
3.4
>>> print(repr(x))
Decimal('3.4')
在调试中,repr() 能揭示对象的真实类型和构造形式,减少误判。
相关概念:print debugging、repr、debugging
4. 在程序中手动启动调试器
Python 3.7+ 可以使用内置函数 breakpoint() 在代码中设置调试入口:
def some_function():
...
breakpoint()
...
程序执行到 breakpoint() 时会进入调试器,可以检查变量、单步执行、查看调用栈等。
旧版本 Python 中常见写法是:
import pdb
pdb.set_trace()
breakpoint() 是现代推荐写法,而 pdb.set_trace() 仍会在旧教程或遗留代码中出现。
相关概念:pdb、breakpoints、debugging
5. 在调试器下运行整个程序
可以用 pdb 模块直接运行脚本:
python3 -m pdb someprogram.py
这样程序会在第一条语句前进入调试器,允许开发者提前设置断点、配置执行路径,并逐步观察程序运行。
常用 pdb 命令包括:
| 命令 | 作用 |
|---|---|
help |
查看帮助 |
w / where |
打印调用栈 |
d / down |
向下移动一个栈帧 |
u / up |
向上移动一个栈帧 |
b loc / break loc |
设置断点 |
s / step |
单步执行 |
c / continue |
继续运行 |
l / list |
列出源码 |
a / args |
查看当前函数参数 |
!statement |
执行 Python 语句 |
断点位置可以是:
b 45 # 当前文件第 45 行
b file.py:45 # file.py 的第 45 行
b foo # 当前文件中的 foo() 函数
b module.foo # 某模块中的 foo() 函数
相关概念:pdb、breakpoints、call stack
练习
Exercise 8.4: Bugs? What Bugs?
练习标题以玩笑方式强调:程序“能运行”并不代表没有 bug。调试是理解程序状态、定位异常和验证假设的重要过程。
关键收获
- traceback 是崩溃分析的第一入口,最后一行通常说明直接原因。
python3 -i script.py可以在脚本崩溃后保留交互式环境,方便检查状态。print()调试简单有效,但输出调试信息时应优先使用repr()。breakpoint()是 Python 3.7+ 推荐的内置调试入口。python3 -m pdb program.py可以从程序开始就进入调试器。pdb支持调用栈查看、断点、单步执行、继续运行和动态执行语句等功能。
可延伸概念
- debugging:程序调试的一般策略与工具。
- traceback:Python 异常调用栈的阅读方法。
- pdb:Python 内置调试器的命令与工作流。
- repl:交互式解释器在调试中的用途。
- repr:对象精确表示与调试输出。
- breakpoints:断点在程序执行控制中的作用。