Files

5.0 KiB
Raw Permalink Blame History

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:断点在程序执行控制中的作用。