4.3 · 调试技巧
目标: 系统隔离 bug。
调试心态
- 复现 —— 找一个稳定触发 bug 的输入。
- 隔离 —— 缩到涉及代码的最小部分。
- 假设 —— 猜原因。
- 测假设 —— 改一处再跑。
- 修 —— 最小改动。
- 加测试 —— 防回归。
技术
1 · print 调试
在可疑处插入 print 显示变量值。
python
def average(nums):
print("DEBUG: nums =", nums)
total = sum(nums)
print("DEBUG: total =", total)
return total / len(nums)1
2
3
4
5
2
3
4
5
低科技但有效。修好后删掉。
2 · 用 IDE 调试器
设断点、逐行执行、检查变量。Thonny、VS Code、PyCharm 都支援。
3 · 纸上追踪表
bug 是逻辑性的时,用笔纸过代码(模块 D 第 2.5 节)。
4 · 二分法(二分搜 bug)
100 行代码重构后出 bug,注释掉新加代码的一半再测。在剩余的一半上重复。
5 · 小黄鸭调试
对无生命物体(或朋友)一行行解释你的代码。说出口的过程常露出 bug。
6 · 与工作版本对比
用了 git,跑 git diff 看程序上次能跑后改了什么。
实例
python
def factorial(n):
result = 1
for i in range(n): # BUG:应为 range(1, n+1)
result *= i # i 从 0 起 → result 变 0!
return result
print(factorial(5)) # 0,不是 1201
2
3
4
5
6
7
2
3
4
5
6
7
调试步骤:
- 复现 ——
factorial(5)返回 0。 - 隔离 —— 只有一个循环和一个乘法。
- 假设 —— 也许范围错。
- 测 —— 在循环里加
print(i, result):0 0 1 0 2 0 3 0 4 01
2
3
4
5 - 啊哈!
i从 0 起,乘 0 → 永远 0。 - 修 ——
range(1, n+1)。
比较不同解法
课程鼓励学生比较同一问题的不同解法在:
- 步数
- 内存使用
- 可读性
养成「有没有更好的方法?」的习惯。
学生常见错误
- 一次改太多 —— 分不清哪修起了作用。
- 随机改(「试试看…」)而非按假设。
- 最终提交前忘删 debug
print。 - 不写抓 bug 的测试防回归。
考试式题目
题(5 分): 程序本该印 1+2+…+n 的和,但
n=5时印 10 不是 15。(a) 识别最可能的错误类型。 (b) 描述能帮忙找原因的三种调试技术。
参考答案:
(a) 逻辑错误 —— 程序跑但和错。
(b) 三种技术:
- 在纸上做追踪表,对 n=5 逐轮过并跟期望对比。
- Print 调试 —— 在循环里加
print(i, total)看运行总和如何演变。 - 用 IDE 调试器步进,在循环设断点,每轮检查变量。
关键要点
- 系统调试:复现 → 隔离 → 假设 → 测 → 修 → 再测。
- 多种技术可用;先用最便宜的。
- 没测试的修复是早晚回来的 bug。
模块 D 总结
自测:
- 能手工追踪 15 行伪代码吗?
- 能在 Python 里从零实现线性查找、min/max/avg 吗?
- 能列 3 种错误类型并举例吗?
- 能描述 3 种调试技术吗?
➡️ 下一模块:模块 E · 社会影响