当前位置:首页>python>每天学习一点Python——手把手教你用VSCode调试Python代码

每天学习一点Python——手把手教你用VSCode调试Python代码

  • 2026-10-16 11:17:23
每天学习一点Python——手把手教你用VSCode调试Python代码

每天学习一点Python——手把手教你用VSCode调试Python代码

大家好!今天我们来学习Python编程中非常重要的一项技能——调试。调试就是找bug、修bug的过程。无论你是编程新手还是有经验的开发者,调试都是必备技能!

一、准备工作

首先确保你安装了:

  1. 1. Python(建议3.8以上版本)
  2. 2. VSCode编辑器
  3. 3. VSCode的Python扩展

二、第一个调试示例

让我们从一个简单的例子开始:

# debug_demo.py
def
 calculate_sum(numbers):
    total = 0
    for
 num in numbers:
        total += num
        print
(f"当前数字: {num}, 累计总和: {total}")
    return
 total

# 测试数据

data = [1, 2, 3, 4, 5]
result = calculate_sum(data)
print
(f"最终结果: {result}")

代码解析:

  • • 第1行:定义了一个函数calculate_sum,它接收一个参数numbers(一个数字列表)
  • • 第2行:初始化变量total为0,用来存储总和
  • • 第3-5行:for循环遍历numbers中的每个数字
  • • 第4行:total += num 等价于 total = total + num,把当前数字加到总和中
  • • 第5行:打印当前数字和累计总和
  • • 第8行:定义测试数据data,是一个包含5个数字的列表
  • • 第9行:调用函数,把测试参数data传进去,计算结果
  • • 第10行:打印最终结果

执行结果:

当前数字: 1, 累计总和: 1
当前数字: 2, 累计总和: 3
当前数字: 3, 累计总和: 6
当前数字: 4, 累计总和: 10
当前数字: 5, 累计总和: 15
最终结果: 15

三、如何在VSCode中开启调试?

方法一:使用调试面板

  1. 1. 点击VSCode左侧活动栏的"运行和调试"图标(看起来像一个甲壳虫趴在三角形上)
  2. 2. 如果是第一次使用,会提示你"创建 launch.json 文件",点击它
  3. 3. 选择"Python"
  4. 4. 这时会在调试框顶部中间位置出现一个绿色的开始调试按钮 ▶,点击它就开始调试了

方法二:快速设置断点

def debug_example():
    name = "Python"
    version = 3.9
    print
(f"语言: {name}, 版本: {version}")

    # 设置断点的方法:点击行号左边的空白区域

    for
 i in range(3):
        print
(f"循环 {i + 1}")

    return
 "调试完成"

# 按F5开始调试

debug_example()

设置断点的步骤:

  1. 1. 找到第6行(for i in range(3):)
  2. 2. 点击行号"6"左边的空白处
  3. 3. 会出现一个红色圆点,这就是断点
  4. 4. 按F5开始调试,程序会在第6行暂停

四、调试界面详解

当你开始调试时,VSCode界面会分成几个区域:

+------------------------------------------+
| 调试控制台    | 变量查看器 | 监视窗口      |
+------------------------------------------+
|               编辑器                     |
| (这里有你的代码,当前执行行会高亮显示) |
+------------------------------------------+
|               调用堆栈                   |
| (显示当前函数调用关系)                 |
+------------------------------------------+

1. 调试控制台(Debug Console)

这里显示程序的输出结果,你还可以在这里输入Python命令,实时查看变量值。

2. 变量查看器(Variables)

这个窗口显示当前作用域的所有变量及其值。比如:

  • • 当程序执行到第6行时,这里会显示:
    name: "Python"
    version: 3.9
    i: 0  (循环计数器)

3. 监视窗口(Watch)

这里可以添加你想特别关注的表达式。比如添加i * 2,就能实时看到这个表达式的值。

五、调试控制按钮

调试窗口顶部有一排按钮,让我们来认识它们:

[▶ 继续] [↷ 单步跳过] [↓ 单步进入] [↑ 单步跳出] [↻ 重新开始] [■ 停止]

按钮图标
名称
快捷键
作用
▶
继续
F5
程序继续执行,直到遇到下一个断点
↷
单步跳过
F10
执行当前行,但不进入函数内部
↓
单步进入
F11
执行当前行,如果这行调用了函数,就进入函数内部
↑
单步跳出
Shift+F11
跳出
当前函数,回到调用它的地方
↻
重新开始
Ctrl+Shift+F5
重新开始调试
■
停止
Shift+F5
停止调试

对比学习:

操作
适用场景
例子
单步跳过
确认某个函数的结果正确,不需要看内部细节
调用len()函数计算列表长度
单步进入
需要查看自定义函数的内部执行过程
查看自己写的calculate_average()函数
单步跳出
在函数内部查看完毕后,快速返回
在复杂函数中查看关键部分后跳出

六、断点的高级用法

1. 条件断点

有时候我们只想在特定条件下暂停程序。比如:

def process_data(items):
    for
 index, item in enumerate(items):
        if
 item > 10:  # 我们只想在item大于10时暂停
            print
(f"发现大数: {item} at index {index}")
        else
:
            print
(f"小数: {item}")

data = [5, 12, 8, 15, 3]
process_data(data)

设置条件断点的方法:

  1. 1. 在第3行if item > 10:的左侧设置普通断点
  2. 2. 右键点击断点(红色圆点)
  3. 3. 选择"编辑断点"
  4. 4. 在表达式框里输入:item > 10
  5. 5. 现在程序只会在item大于10时暂停

2. 日志点(Logpoint)

有时候我们不想暂停程序,只想在特定位置输出信息:

def calculate_stats(numbers):
    total = sum(numbers)
    count = len(numbers)
    average = total / count
    return
 total, average

data = [85, 90, 78, 92, 88]
result = calculate_stats(data)

设置日志点:

  1. 1. 在第2行的下一行的行号左侧右键(因为如果直接在第二行添加,会报错:name 'total' is not defined) → 选择"添加记录点"
  2. 2. 输入日志信息:计算总和: {total}
  3. 3. 程序执行到这里时会在 调试控制台 输出日志"计算总和: 433",但程序本身不会暂停
  4. 4. 注意:直接点击程序执行按钮不会执行该记录点,需要按F5来触发调试模式。

七、变量查看技巧

让我们看一个更复杂的例子:

def analyze_students():
    students = {
        "小明"
: {"年龄": 18, "成绩": 85},
        "小红"
: {"年龄": 17, "成绩": 92},
        "小刚"
: {"年龄": 19, "成绩": 78}
    }

    total_score = 0
    student_count = 0

    for
 name, info in students.items():
        total_score += info["成绩"]
        student_count += 1
        current_avg = total_score / student_count

        print
(f"学生: {name}, 成绩: {info['成绩']}, 当前平均分: {current_avg:.1f}")

    return
 total_score, current_avg

# 调试时观察变量变化

result = analyze_students()
print
(f"最终结果: 总分={result[0]}, 平均分={result[1]:.1f}")

调试时你可以:

  1. 1. 悬停查看:鼠标悬停在变量名上,会显示当前值
  2. 2. 在调试控制台直接计算:
    >>> total_score * 2
    510
    >>> [name for name in students.keys()]
    ['小明', '小红', '小刚']
  3. 3. 添加监视表达式:在Watch窗口添加current_avg > 85,实时查看条件是否成立

八、调试配置详解

VSCode的调试配置文件是launch.json,它控制着调试的行为:

{
    "version"
: "0.2.0",
    "configurations"
: [
        {

            "name"
: "Python: 调试当前文件",
            "type"
: "python",
            "request"
: "launch",
            "program"
: "${file}",
            "console"
: "integratedTerminal",
            "stopOnEntry"
:false,
            "justMyCode"
:true,
            "args"
: []
        }

    ]

}

参数解释:

  • • "name": 调试配置的名称,显示在调试下拉菜单中
  • • "type": 调试器类型,Python就写"python"
  • • "program": "${file}"表示调试当前打开的文件
  • • "console": "integratedTerminal"表示在VSCode的内置终端中运行
  • • "stopOnEntry": false表示开始时不暂停
  • • "justMyCode": true表示只调试你自己的代码,不进入Python内置函数
  • • "args": 命令行参数,比如可以设置["--input", "data.txt"]

九、unittest测试

单元测试是保证代码质量的重要手段,VSCode可以很好地调试测试代码:

# test_debug.py
import
 unittest

class
 TestMathOperations(unittest.TestCase):
    def
 test_addition(self):
        result = 1 + 2  # 在这行添加断点
        self
.assertEqual(result, 3)
        print
(f"加法测试通过: 1 + 2 = {result}")

    def
 test_division(self):
        # 设置断点调试异常情况

        with
 self.assertRaises(ZeroDivisionError):
            result = 5 / 0

    def
 test_list_operations(self):
        items = [1, 2, 3, 4, 5]
        # 使用调试器观察列表变化

        squared = [x**2 for x in items]
        print
(f"原始列表: {items}")
        print
(f"平方后: {squared}")
        self
.assertEqual(squared, [1, 4, 9, 16, 25])

if
 __name__ == '__main__':
    unittest.main()

逐行解释

第1行:导入unittest模块

import unittest
  • • unittest 是Python自带的单元测试框架
  • • 提供测试类、断言方法等功能

第3-4行:定义测试类

class TestMathOperations(unittest.TestCase):
  • • 创建一个测试类 TestMathOperations
  • • 必须继承unittest.TestCase,这是测试类的标准写法
  • • 类名通常以 Test 开头,但这不是必须的

第5-8行:第一个测试方法 - 加法测试

def test_addition(self):  # 方法名必须以test_开头,才会被unittest发现
    result = 1 + 2   # 执行计算:1 + 2 = 3
    self
.assertEqual(result, 3)  # 断言:验证result是否等于3
    print
(f"加法测试通过: 1 + 2 = {result}")  # 输出信息
  • • 方法名:必须以 test_ 开头(unittest的约定)
  • • self.assertEqual(a, b):断言a等于b,如果不相等则测试失败

第10-14行:第二个测试方法 - 除法测试(验证异常)

def test_division(self):
    # 设置断点调试异常情况

    with
 self.assertRaises(ZeroDivisionError):  # 验证是否会抛出ZeroDivisionError
        result = 5 / 0  # 这行代码会抛出除零异常
  • • self.assertRaises(异常类型):验证代码块是否会抛出指定类型的异常
  • • 5 / 0:一定会抛出 ZeroDivisionError
  • • 这个测试期望的行为是:5 / 0 抛出异常,且被 assertRaises 捕获,测试通过

第16-23行:第三个测试方法 - 列表操作测试

def test_list_operations(self):
    items = [1, 2, 3, 4, 5]  # 创建列表
    # 使用调试器观察列表变化

    squared = [x**2 for x in items]  # 列表推导式:计算每个元素的平方
    print
(f"原始列表: {items}")  # 打印原始列表
    print
(f"平方后: {squared}")  # 打印平方后的列表
    self
.assertEqual(squared, [1, 4, 9, 16, 25])  # 断言平方结果是否正确

第25-26行:主程序入口

if __name__ == '__main__':
    unittest.main()  # 运行所有测试
  • • unittest.main():自动发现并运行所有以 test_ 开头的方法
  • • 这是运行unittest测试的标准写法

如何运行和调试:

方法1:直接运行测试

# 在终端运行
python test_debug.py

输出结果:

加法测试通过: 1 + 2 = 3
..原始列表: [1, 2, 3, 4, 5]
平方后: [1, 4, 9, 16, 25]
.
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

输出结果解析:

  • • .:每个点代表一个测试用例通过。这里有3个点,表示3个测试都通过了
  • • 加法测试通过: 1 + 2 = 3:这是test_addition方法中的print输出
  • • 原始列表: [1, 2, 3, 4, 5] 和 平方后: [1, 4, 9, 16, 25]:这是test_list_operations方法中的print输出
  • • Ran 3 tests in 0.001s:表示运行了3个测试用例,耗时0.001秒
  • • OK:所有测试都通过了

方法2:调试测试用例(推荐)

步骤1:设置断点

  • • 在第6行:result = 1 + 2
  • • 第12行:result = 5 / 0
  • • 第19行:squared = [x**2 for x in items]

步骤2:启动调试(按F5)

步骤3:使用测试专用调试配置(修改 .vscode/launch.json):

{
    "version"
: "0.2.0",
    "configurations"
: [
        {

            "name"
: "Python: 调试单元测试",
            "type"
: "debugpy",
            "request"
: "launch",
            "program"
: "-m",
            "args"
: [
                "unittest"
,
                "${file}"

            ]
,
            "console"
: "integratedTerminal"
        }

    ]

}

修改前后配置对比详解:

修改前配置解析:

{
    "version"
: "0.2.0",                     // 配置文件的版本号,固定为0.2.0,这是VSCode调试配置的标准版本
    "configurations"
: [                     // 配置数组,可以包含多个调试配置
        {

            "name"
: "Python 调试程序: 当前文件",  // 配置名称,显示在调试下拉列表中
            "type"
: "debugpy",              // 调试器类型,Python使用debugpy
            "request"
: "launch",            // 启动方式,launch表示启动新的调试会话
            "program"
: "${file}",           // 要调试的程序,${file}表示当前打开的文件
            "console"
: "integratedTerminal" // 输出控制台类型,integratedTerminal表示使用VSCode内置终端
        }

    ]

}

修改后配置解析:

{
    "version"
: "0.2.0",                     // 版本号不变
    "configurations"
: [
        {

            "name"
: "Python: 调试单元测试",  // 修改了配置名称,更明确
            "type"
: "debugpy",              // 调试器类型不变
            "request"
: "launch",            // 启动方式不变
            "program"
: "-m",                // 重要改变:-m表示以模块方式运行Python代码
            "args"
: [                       // 新增:参数数组,传递给Python程序
                "unittest"
,                 // 第1个参数:表示要运行unittest模块
                "${file}"
                   // 第2个参数:当前文件名
            ]
,
            "console"
: "integratedTerminal" // 输出控制台不变
        }

    ]

}

关键变化解释:

  1. 1. program参数:从"${file}"改为"-m"
    • • "${file}":直接运行当前Python文件
    • • "-m":以模块方式运行,配合args参数使用
  2. 2. 新增args参数:["unittest", "${file}"]
    • • 这相当于在命令行执行:python -m unittest test_debug.py
    • • -m unittest:告诉Python以模块方式运行unittest
    • • "${file}":要测试的文件名
  3. 3. 运行方式对比:
    • • 修改前:直接运行Python脚本,不识别测试用例
    • • 修改后:使用unittest框架运行,能自动发现并运行所有test_开头的测试方法

调试时的观察重点

1. 观察 test_addition:

  • • 在 result = 1 + 2 处暂停后,按 F10 单步执行
  • • 观察 result 变量的值变化
  • • 在 self.assertEqual(result, 3) 处,验证断言条件

2. 观察 test_division:

  • • 在 result = 5 / 0 处设置断点
  • • 按 F10 执行到这行时,会抛出异常
  • • 观察异常如何被 assertRaises 上下文管理器捕获

3. 观察 test_list_operations:

  • • 在 squared = [x**2 for x in items] 处设置断点
  • • 使用 F11 可以进入列表推导式的内部循环
  • • 观察每次循环时 x 和 x**2 的值
  • • 观察 squared 列表如何逐步构建

十、实用调试技巧

技巧1:最小化复现

当遇到bug时,不要试图调试整个大程序。先创建一个最小的测试用例:

# 原程序可能很复杂,但bug可能很简单
# 比如发现成绩计算不对,可以创建最小测试:


def
 test_calculation():
    # 测试用例1:正常情况

    scores = [80, 90, 100]
    avg = sum(scores) / len(scores)
    print
(f"测试1 - 成绩: {scores}, 预期平均分: 90.0, 实际: {avg}")

    # 测试用例2:边界情况

    scores = []
    try
:
        avg = sum(scores) / len(scores)
    except
 ZeroDivisionError:
        print
("测试2 - 空列表会报错,需要处理!")

    return
 "测试完成"

技巧2:二分法查找bug

如果不知道bug在哪,可以用二分法:

  1. 1. 在代码中间设置断点
  2. 2. 查看前半部分是否正常
  3. 3. 如果不正常,在前半部分的中间再设断点
  4. 4. 重复直到找到问题

十一、常见问题与解决方案

问题1:调试器无法启动

可能原因:没有选择正确的Python解释器
解决方法:

  1. 1. 按Ctrl+Shift+P打开命令面板
  2. 2. 输入"Python: Select Interpreter"
  3. 3. 选择正确的Python版本

问题2:断点不生效

可能原因:代码有语法错误
解决方法:

  1. 1. 检查代码是否有红色波浪线
  2. 2. 确保代码能正常运行(无语法错误)

问题3:变量值显示为"undefined"

可能原因:该变量在当前作用域未定义
解决方法:

  1. 1. 确保程序执行到了变量定义的地方
  2. 2. 检查变量名是否拼写正确

十二、调试工作流程总结

一个好的调试流程应该是:

  1. 1. 重现问题:确保你能稳定地重现bug
  2. 2. 定位范围:猜测bug可能出现在哪个函数或代码块
  3. 3. 设置断点:在可疑位置设置断点
  4. 4. 单步执行:使用F10/F11逐步执行,观察变量变化
  5. 5. 验证假设:通过查看变量值验证你的猜测
  6. 6. 修复测试:修复后重新测试,确保问题解决

十三、动手练习

现在轮到你了!尝试调试下面的代码:

def find_max_number(numbers):
    # 这个函数应该返回列表中的最大数,但有bug

    max_num = numbers[0]

    for
 i in range(1, len(numbers)):
        if
 numbers[i] > max_num:
            numbers[i] = max_num  # 这一行有问题!

    return
 max_num

# 测试用例

test_data = [3, 7, 2, 9, 5]
result = find_max_number(test_data)
print
(f"列表 {test_data} 中的最大值是: {result}")
print
(f"正确结果应该是: {max(test_data)}")

执行结果:

列表 [3, 7, 2, 9, 5] 中的最大值是: 3
正确结果应该是: 9

🔍 挑战:使用今天学到的调试技巧,找出bug在哪里并修复它!


📌 小贴士汇总

Tip 1: 调试前先确保代码没有语法错误
Tip 2: 善用"单步跳过"(F10)提高调试效率
Tip 3: 在Watch窗口添加关键表达式,实时监控
Tip 4: 调试完成后记得清除不必要的断点
Tip 5: 复杂的bug可以先用print语句定位大致范围,再用调试器详细查看

十四、总结

今天我们一起学习了:

  1. 1. VSCode调试器的基本使用:如何启动调试、设置断点
  2. 2. 调试控制按钮的功能:继续、单步执行、单步跳过等
  3. 3. 高级调试技巧:条件断点、日志点、监视表达式
  4. 4. 实用的调试工作流程
  5. 5. 单元测试的调试方法:如何配置和调试unittest测试用例

记住:调试不是猜谜游戏,而是一个科学的查找过程。通过今天学习的方法,你可以像侦探一样,一步步追踪bug的踪迹。

调试技能需要练习,建议你:

  1. 1. 故意写一些有bug的代码,练习调试
  2. 2. 从简单的问题开始,逐步挑战更复杂的bug
  3. 3. 养成调试的习惯,而不是一味地猜测

📦 资源获取提示

关注「码农自习室」,后台回复关键词 Python学习,即可获取本文完整代码,一起动手掌握高效编程的核心技巧!


❤️ 支持我们

如果觉得本文对你有帮助,欢迎点赞 + 关注,您的支持是我们持续创作优质内容的最大动力!


📚 学习资源说明

本文内容是基于《Python Basics: A Practical Introduction to Python 3》(Real Python)一书的学习笔记整理。
这本书是一本非常优秀的Python入门教材,推荐给所有想要系统学习Python的朋友们。

这本书的特点:

  • • ✅ 完全面向编程新手
  • • ✅ 每个概念都有代码示例
  • • ✅ 包含大量练习题
  • • ✅ 由经验丰富的Python开发者编写

跟着这本书学习,配合我的笔记整理,相信你能更快掌握Python编程!

让我们一起坚持学习,每天进步一点点!💪

最新文章

随机文章