语法错误(syntax error)让程序无法开始。运行时错误(runtime error)让程序在中途停下。逻辑错误(logic error)让程序跑完,但答案是错的。知道是哪一种,就知道该往哪里找。
这一课接在 测试缩进与分支结构 之后,属于 过渡到 Python 与代码运行。
三种错误有什么不同?
| 错误 | 何时出现 | 你会看到 | 怎样找 |
|---|---|---|---|
| 语法错误 | 任何代码运行之前 | 错误信息和行号 | 读那一行,检查冒号、括号、引号、= 与 == |
| 运行时错误 | 运行过程中 | 程序停下并显示信息 | 读信息,追踪到那一行 |
| 逻辑错误 | 运行结束之后 | 错误结果,没有信息 | 用已知答案测试,追踪计算过程 |
语法错误和运行时错误会自己报错。逻辑错误是悄无声息的,所以当你只检查“有没有跑起来”时,丢分的往往就是它。
例题
任务:求三个数的平均值。用 6、9 和 12 测试,正确的平均值是 (6 + 9 + 12) / 3 = 27 / 3 = 9。
def average(a, b, c):
return a + b + c / 3
print(average(6, 9, 12))
第 1 步,能运行吗? 能。没有语法错误或运行时错误,所以如果有问题,就在逻辑上。
第 2 步,追踪表达式。 除法先于加法,所以 Python 先算 c / 3:12 / 3 = 4。然后 6 + 9 + 4 = 19。
第 3 步,比较。 19 不等于 9,所以这是逻辑错误。
第 4 步,加括号修正。
def average(a, b, c):
return (a + b + c) / 3
现在 (6 + 9 + 12) / 3 = 9.0。Python 显示 9.0,是因为 / 总是给出小数结果。
要提防的错误
常见的失误是以为没有错误信息的程序就是对的。
错误答案: “我运行了,它输出 19,所以没问题。”
程序是跑起来了,但没有人把 19 和预期的 9 比较。拿已知答案来核对,才能暴露逻辑错误。
改正的做法是在运行代码之前先手算出预期答案。这样,比较的结果会告诉你问题出在代码,还是出在你对题目的理解。
真正的语法错误看起来不同。在 if mark = 50: 中,单个 = 是赋值,却用在需要比较的地方,所以 Python 拒绝运行并报告语法错误。正确写法是 if mark == 50:。
自我检测
1. print("Hi" 少了右括号,这是哪一种错误?
查看答案
语法错误。括号从未闭合,Python 读不懂这一行,程序无法开始。
2. 这个函数应该返回列表的总和。用 [2, 4] 调用时,它属于哪一种错误?
def total(values):
t = 0
for n in values:
t = n
return t
查看答案
逻辑错误。它能运行,但 t = n 每次都替换总和而不是累加,所以返回 4 而不是 6。这一行应该是 t = t + n。
3. print(10 / 0) 是哪一种错误?
查看答案
运行时错误。代码合法,但除以零是不可能的,所以程序停下并显示 ZeroDivisionError 信息。
接下来学什么
下一课,使用安全的浏览器运行环境,无风险地运行这些例子。你可以在 Python 推理沙盒 里测试 average 函数,并和 受限伪代码追踪训练器 对照。
如果错误答案总能通过你自己的检查,我们的 线上一对一计算机科学补习 可以陪你训练测试习惯。