跳到主要内容

🔍 调试技巧

代码跑不通、输出不对、莫名报错——每个程序员都会遇到。"调试"就是找到问题原因的过程。本节介绍三种最实用的方法:print 调试、pdb 断点调试、IDE 可视化调试,从简单到高效逐步升级。

🎯 本节要点
  • print 是最快的调试手段,适合快速排查
  • breakpoint() + pdb 可以暂停程序、检查变量、单步执行
  • IDE 调试器(VS Code / PyCharm)提供图形化断点、变量监视、调用栈
  • 遇到报错先读 Traceback,它会告诉你出错的文件、行号、调用链

方法一:print 调试

最朴素但最快的方法——在关键位置插入 print,看变量值:

Python
def calculate_average(numbers):
print(f"输入: {numbers}") # 调试:确认输入
total = sum(numbers)
print(f"总和: {total}") # 调试:确认计算
avg = total / len(numbers)
print(f"平均值: {avg}") # 调试:确认结果
return avg
Python
# 1. 打印变量名 + 值
x = 42
print(f"{x = }") # Python 3.8+ → x = 42

# 2. 打印类型
print(type(x)) # <class 'int'>

# 3. 打印位置信息
import traceback
traceback.print_stack() # 打印当前调用栈

# 4. 条件调试:只在特定条件下打印
for i in range(100):
if i % 10 == 0:
print(f"处理到第 {i} 项")
print 调试的局限
  • 需要改代码 → 改完记得删掉
  • 看不到完整的调用栈和变量作用域
  • 多个变量时输出杂乱

适合简单快速的问题。复杂问题请升级到 pdb 或 IDE 调试器。

方法二:pdb 断点调试

Python 自带调试器 pdb,可以在代码中设置断点,暂停执行后交互式检查变量。

使用 breakpoint()

Python 3.7+ 推荐用 breakpoint() 设置断点:

Python
def calculate_average(numbers):
total = sum(numbers)
breakpoint() # 程序执行到这里会暂停
avg = total / len(numbers)
return avg

calculate_average([10, 20, 30])

运行后程序暂停,进入 pdb 交互界面:

输出
> /home/user/project/calc.py(6)calculate_average()
-> avg = total / len(numbers)
(Pdb)

pdb 常用命令

输出
# 在 pdb 提示符下输入:

n # 执行下一行(next)
s # 进入函数内部(step)
c # 继续运行到下一个断点(continue)
p variable # 打印变量值(print)
pp variable # 格式化打印(pretty print)
l # 显示当前代码位置(list)
w # 显示调用栈(where)
q # 退出调试器(quit)
h # 查看帮助(help)

实际例子

Python
def process_data(data):
result = []
for item in data:
processed = transform(item)
breakpoint() # 暂停,检查每轮循环
result.append(processed)
return result

暂停后可以逐行查看 itemprocessed 的值:

Output
> /home/user/project/main.py(6)process_data()
-> result.append(processed)
(Pdb) p item
{'name': 'Alice', 'score': 85}
(Pdb) p processed
{'name': 'alice', 'score': 85, 'grade': 'B'}
(Pdb) n
> /home/user/project/main.py(4)process_data()
-> for item in data:

关闭 pdb

运行时设置环境变量可以跳过所有 breakpoint()

Shell
PYTHONNOUSERSITE=1 python -c "breakpoint()" # 不会暂停

或者在 .env 文件中加 PYTHONBREAKPOINT=0

方法三:IDE 可视化调试

VS Code 和 PyCharm 都提供图形化调试器,体验远优于 pdb。

VS Code 调试

  1. 在代码行号左侧点击,添加断点(红色圆点)
  2. F5 或点击"运行和调试"
  3. 程序暂停时:左侧显示变量值,底部可输入表达式

配置 launch.json

{
"version": "0.2.0",
"configurations": [
{
"name": "Python: 当前文件",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}

PyCharm 调试

  1. 行号左侧点击添加断点
  2. 右键文件 → Debug
  3. 暂停后底部面板显示:Variables(变量)、Watches(监视)、Console(控制台)
IDE 调试 vs pdb
  • pdb:轻量、终端内完成,适合远程服务器或快速排查
  • IDE 调试器:可视化、支持条件断点、变量修改、多线程调试,日常开发首选

两种方式可以混用——IDE 调试器底层也是 pdb。

读懂 Traceback

Python 报错时会打印 Traceback(回溯信息),这是调试的起点:

Output
Traceback (most recent call last):
File "main.py", line 10, in <module>
result = process(data)
File "main.py", line 5, in process
value = data["key"]
KeyError: 'key'

从下往上看:

  1. 最后一行:异常类型和消息 — KeyError: 'key'
  2. 倒数第二行:出错的代码 — value = data["key"]
  3. 再往上:调用链 — 谁调用了这个函数
调试思路
  1. 看异常类型:KeyError → 字典缺键、ValueError → 值不对、TypeError → 类型错误
  2. 看出错行号:line 5 → 打开文件看第 5 行
  3. 看调用链:从下往上追踪调用路径
  4. breakpoint() 在出错行之前,检查变量状态

常见报错速查

异常常见原因解决方向
NameError变量未定义检查拼写、是否在作用域内
TypeError类型不匹配检查传参类型,str(123) 转换
ValueError值不合理检查输入范围
KeyError字典缺键dict.get(key, default)key in dict
IndexError列表越界检查索引范围,len(list)
AttributeError对象无此属性检查拼写、import 是否正确
ImportError导入失败检查包名、是否安装、版本兼容
FileNotFoundError文件不存在检查路径、工作目录

实战:调试一个有 bug 的程序

下面这段代码有问题,试着用上面的方法找出并修复:

Python
# buggy.py

def find_longest(words):
"""找出列表中最长的单词"""
longest = ""
for word in words:
if len(word) > len(longest):
longest = word
return longest

words = ["apple", "banana", "cherry", "date"]
result = find_longest(words)
print(f"最长的单词是:{result}")
print(f"长度是:{result.length}") # ← bug 在这里

调试步骤

  1. 运行看报错
Shell
uv run python buggy.py
Output
最长的单词是:cherry
Traceback (most recent call last):
File "buggy.py", line 12, in <module>
print(f"长度是:{result.length}")
AttributeError: 'str' object has no attribute 'length'
  1. 读 TracebackAttributeError + 'str' object has no attribute 'length' → 字符串没有 .length 属性

  2. 修复:Python 字符串用 len() 函数,不是 .length 属性

Python
print(f"长度是:{len(result)}") # ✅ 修复

调试清单

遇到问题时按这个顺序排查:

  1. 读报错信息 — 异常类型 + 行号能解决 80% 的问题
  2. print 关键变量 — 在报错行之前打印变量值
  3. 加断点 — 用 breakpoint() 或 IDE 断点逐行检查
  4. 简化复现 — 去掉无关代码,找到最小复现步骤
  5. 搜索 — 把错误信息贴到搜索引擎,通常有人遇到过同样的问题