Kodokon kodokon.com

读懂报错信息

学会解读报错信息,而不是直接关掉它:类型、文件、行号和调用栈。

8 分钟 · 3 题

在 Kodokon 中打开本课

报错不是惩罚。你的电脑没有在评判你,也没有在嘲笑你:它只是发现自己不知道该怎么办,于是告诉你原因。这就像导航说“正在重新规划路线”一样——那不是责备,那是信息。新手的本能反应是看都不看就关掉那个红色窗口。开发者的本能反应则是慢慢读,一直读到最后。这往往是机器唯一一次用大白话跟你说话的时刻。

几乎所有的报错信息都包含同样几样东西。错误的类型,把它归入一个大的类别。信息本身,用一句话说明哪里不对。涉及的文件行号,准确告诉你该去哪里看。有时还有一份调用栈(stack trace):程序在崩溃之前所经过的一系列步骤。

PYTHON
Traceback (most recent call last):
  File "shopping.py", line 12, in <module>
    total = price * quantity
NameError: name 'quantity' is not defined
一条 Python 报错:文件、第 12 行、NameError 类型以及它的解释。

在上面这个例子里,一切都写清楚了。文件是 shopping.py,行号是 12,类型是 NameError,信息说的是 name 'quantity' is not defined,也就是“名字 quantity 没有被定义”。用大白话说:在第 12 行,你用了一个自己从来没创建过的变量 quantity,或者你把它的名字拼错了。不需要什么复杂的排查——答案早就写在报错信息里了。

Python 的调用栈要从下往上读:最后一行给出类型和解释,紧挨着它上面的就是出问题的文件和行号。当调用栈很长时,去找第一行提到你自己的文件的那一行。那些提到陌生文件、名字奇怪的行,属于你正在使用的库:99% 的情况下有问题的不是它们,而是你调用它们的方式。

JAVASCRIPT
Uncaught TypeError: Cannot read properties of
undefined (reading 'name')
    at showProfile (app.js:24:18)
    at start (app.js:41:3)
浏览器控制台里也是同样的逻辑:文件 app.js,第 24 行,第 18 列。

有几种说法反复出现,认出它们很划算。not defined 表示你用的这个名字在这个位置并不存在。undefined 表示这个东西存在,但没有任何值。unexpected 表示程序原本期待的是别的东西,通常是漏了一个括号或引号。permission denied 指向的是权限问题,而不是代码问题。而 no such file or directory 表示你写的路径根本不通向任何地方。

知识检测

确认你已牢记本课的重点内容。

  1. 报错信息里的哪一部分告诉你该先去哪里看?
    • 文件名和行号
    • 屏幕上文字的颜色
    • 报错信息的总长度
    • 你操作系统的名称
  2. Python 的调用栈应该按什么方向读?
    • 从上往下:第一行给出解决办法
    • 从下往上:最后一行给出类型和解释
    • 怎么读都行,它纯粹是装饰
  3. 这个程序停在了 NameError: name 'count' is not defined。空格里该写哪个名字才能修好它?
    price = 10
    ___ = 3
    total = price * count
    print(total)
    • count
    • total
    • price
    • number