PyCharm 调试参考
本章承接上一章的小车案例,集中整理 PyCharm 的断点、变量查看、单步执行和复核操作,作为选读参考。使用 VS Code 时,可对照这些通用步骤,在 Run and Debug 中完成相同操作。
截图说明
本章暂时沿用旧版 PyCharm 截图。截图中的工程路径、代码行号和部分按钮样式可能与当前课件不同,操作时以正文代码和自己电脑上的 PyCharm 界面为准。
断点设置与调试启动
先使用上一章小车案例中的尚未修复原始程序。断点可以让程序运行到指定位置时暂停,我们先在 average_speed() 的除法语句旁边单击,设置断点:

然后从主程序旁边的运行按钮中选择 Debug:

PyCharm 会启动程序并打开调试窗口:

在 Console 中输入 s,重新触发刚才的问题:

程序执行到断点或异常位置后会暂停:

到这里先确认两件事:
- 当前停在
self.odometer / self.time。 - Variables 区域显示
self.time的值为0。
断点让我们看到了程序在这一刻的真实状态。
调试状态查看
程序暂停后,重点查看调用栈和变量。其他工具都围绕这两类信息展开。
调用栈
调试窗口中的 Frames 会显示函数调用过程。当前案例中,可以看到程序从主流程进入 average_speed()。
调用栈和 Traceback 表达的是同一条调用关系:Traceback 是异常发生后的记录,调试窗口则允许我们在程序暂停时逐层查看。
点击不同的调用层,可以回到对应代码位置,并查看那一层可以访问的变量。
Variables 与内联值
Variables 区域会列出当前作用域中的对象和变量。展开 self 后,可以看到:
odometer当前为0。speed当前为0。time当前为0。
PyCharm 还会把部分变量值直接显示在编辑器中:

内联变量值适合快速浏览,Variables 更适合展开对象并检查详细状态。
监视变量(Watches)
如果需要持续观察某个变量,可以把它添加到 Watches:

例如,在入口或 main() 的暂停位置监视 my_car.time。进入实例方法后,也可以监视 self.time,表达式要使用当前调用层能够访问的名称。程序刚启动时,它的值是 0:

重新启动后输入 a,沿正常路径继续执行,它会随着 step() 的调用发生变化:

Watches 适合回答:
- 变量什么时候发生了变化?
- 它是否在预期的位置变化?
- 最终结果为什么和预期不同?
表达式求值(Evaluate Expression)
Evaluate Expression 可以在当前暂停位置临时计算表达式:

例如,可以计算:
self.time == 0也可以查看:
self.odometer / 1这些表达式只用于帮助判断当前状态,不会替代代码中的正式处理逻辑。避免在不了解副作用的情况下调用会修改数据的方法。
程序执行控制
只看一个暂停位置还不够时,可以让程序一行一行向下执行。常用操作集中在单步调试工具栏中:
下面的快捷键以截图所用的 PyCharm 键位为例。如果本机键位不同,可以通过按钮提示或 PyCharm 的 Keymap 设置确认。
Step Over
快捷键:F8
执行当前行并停到下一行。当前行调用函数时,Step Over 会完成这次调用,但不会进入函数内部。
只想查看当前函数的主流程时,优先使用 Step Over。
Step Into
快捷键:F7
当前行调用函数时,Step Into 会进入函数内部:

怀疑问题发生在被调用函数中时,可以使用 Step Into。它也可能进入标准库或第三方库代码。
Step Into My Code
快捷键:Alt + Shift + F7
它同样会进入函数,但优先进入自己项目中的代码,可以减少跳入库源码的情况。
Step Out
快捷键:Shift + F8
已经进入函数内部,但不需要继续逐行查看时,可以使用 Step Out 运行完当前函数,回到调用它的位置。
Resume Program
快捷键:F9
继续运行程序,直到下一个断点、触发配置的异常暂停或程序结束:

已经检查完当前位置,希望直接观察下一次暂停时,可以使用 Resume Program。
修改与复核
PyCharm 可以使用 Surround With 快速包裹选中的代码,也可以直接手动编写判断:

修改 average_speed():
def average_speed(self):
if self.time == 0:
return 0
return self.odometer / self.time修改后重新执行原来的操作:
- 启动程序后立即输入
s,确认不再抛出ZeroDivisionError。 - 确认平均速度显示为
0。 - 输入
a让小车运行,再次输入s。 - 确认
time、odometer和平均速度会按预期变化。
如果产品规则要求“小车没有行驶时不能计算平均速度”,也可以改成输出提示。调试负责还原事实,最终怎样修改仍然要由程序需求决定。
基础调试练习
第一次使用调试功能,先完成下面两个练习。
练习 1:断点检查变量
使用上一章小车案例中的原始程序完成本练习;修复版会在 time == 0 时提前返回,首次输入 s 不会到达除法语句。
- 在
average_speed()的除法语句设置断点。 - 使用 Debug 模式启动程序。
- 输入
s。 - 程序暂停后,展开
self,找到time和odometer。 - 使用 Evaluate Expression 计算
self.time == 0。
这个练习的目标是养成习惯:不要靠猜测判断变量值,让程序停下来直接检查。
练习 2:单步检查流程
先应用前面的除零修复,确保 average_speed() 能正常返回,再执行下面的步骤:
- 在处理
action == "S"的位置设置断点。 - 使用 Debug 模式启动程序并输入
s。 - 使用 Step Into 进入
average_speed()。 - 使用 Step Out 回到调用位置。
- 使用 Step Over,观察什么时候执行
self.step()。
这个练习用于确认代码的真实执行顺序。
熟悉以后,在修复版程序中设置两个断点,使用 Resume Program 在两个位置之间继续运行;再分别练习 Step Over、Step Into 和 Step Out,比较它们停下来的位置。
小结
本章重点掌握五件事:
- 排错先复现问题,写清预期结果和实际结果。
- Traceback 帮助定位失败位置,输出、日志和断点帮助确认运行状态。
- 修复方案要符合需求,程序没有报错也可能存在逻辑错误。
- 修改后重跑失败操作、正常操作和边界情况,用回归检查保留验证过程。
- AI 的原因分析和修改建议需要通过实际运行核对。