为什么要用调试器不用print
很多新手程序员定位 bug 靠 print 大法:在可疑位置插入 print,看输出猜问题。简单问题能搞定,复杂逻辑(循环、异步、嵌套调用)print 就混乱了。VSCode 内置了专业调试器,能让你在任意位置暂停、查看所有变量、单步执行,bug 定位效率比 print 快 5-10 倍。
第一步:理解调试器核心概念
- 断点——告诉调试器’在这里暂停’
- 单步执行——一行一行执行,实时观察变量变化
- 变量监控——查看当前作用域所有变量值
- 调用栈——查看函数被谁调用
- 表达式求值——运行时执行任意代码片段
第二步:安装调试环境
以 Python 为例:
- VSCode 安装 Python 扩展(Microsoft 出品)
- 系统安装 Python 3.x
- 首次打开 .py 文件 VSCode 自动检测解释器
- 点击左侧调试图标(虫子图标)进入调试视图
其他语言类似:JS 装 Node.js、Go 装 dlv、Java 装 Extension Pack。
第三步:下第一个断点
打开 Python 文件,在代码行号左侧点击出现红点 = 断点。运行调试(按 F5),代码执行到断点行暂停,左侧显示当前所有变量值。
第四步:单步执行三剑客
调试工具栏三个核心按钮:
- 继续(F5)——执行到下一个断点
- 单步跳过(F10)——执行当前行,不进入函数内部
- 单步进入(F11)——进入当前行调用的函数内部
- 单步跳出(Shift+F11)——跳出当前函数
实战:定位 ‘为什么这个变量值不对’ 时:
- 在该变量定义前下断点
- 单步进入赋值表达式
- 观察每一步变量值变化
- 找到值与预期不符的那一步
第五步:条件断点
循环里想知道第 100 次迭代发生了什么?普通断点会停 100 次。条件断点只在你指定的条件为真时停:
- 右键断点 → ‘编辑断点’
- 输入表达式,如 i == 100 或 user_id == 1234
配合循环调试非常高效。
第六步:日志断点
不想暂停只想记录?日志断点:
- 右键空白处 → ‘添加日志断点’
- 输入日志消息,如 ‘当前 i={i}, user={user}’
代码执行到这里会在调试控制台输出消息,不影响程序运行。比 print 更优雅。
第七步:变量监控
调试时左侧’变量’面板自动显示当前作用域所有变量:
- 局部变量
- 全局变量
- 闭包变量
也可以在’监视’面板添加自定义表达式:
- data[‘users’][0][‘name’]——深层对象属性
- len(items)——动态计算
- result == expected——断言检查
第八步:调用栈分析
左侧’调用堆栈’面板显示当前函数的调用链:
- 栈顶——当前执行的函数
- 下方——调用链上一层
- 点击任何一层——可以查看那层时的所有变量
遇到 ‘A 函数被错误调用’ 的 bug 时,调用栈能让你快速看到是 B 还是 C 调用了 A。
第九步:launch.json 配置
复杂项目需要定制调试配置,按 .vscode/launch.json:
Python Flask 项目示例:
{
version: ‘0.2.0’,
configurations: [
{
name: ‘Flask’,
type: ‘debugpy’,
request: ‘launch’,
module: ‘flask’,
env: { FLASK_APP: ‘app.py’, FLASK_ENV: ‘development’ },
args: [‘run’, ‘–host=0.0.0.0’]
}
]
}
支持 Python、Node.js、Java、Go、C/C++ 等多种配置模板。
第十步:远程调试
线上环境出问题,本地复现不了?远程调试:
- 服务器启动应用时带调试参数
- 本地 VSCode 新建远程调试配置,连接到服务器端口
- 本地断点同步生效,能调试远程代码
Python 用 debugpy、Node 用 –inspect、Java 用 JDWP。
效率提升
对比 print 调试:用调试器后,定位 1 个复杂 bug 时间从平均 1 小时降到 10 分钟,效率提升 6 倍。关键技巧:
- 循环用条件断点,不要反复 F5
- 复杂对象用监视面板,别在变量面板里点开看
- 异步代码切记断点要设在 await 之后
- 线上问题用远程调试,避免’本地又复现不了’