在 Visual Studio 中调试 Python 代码

Visual Studio 为 Python 提供了全面的调试体验。 在本文中,你将探究如何将调试程序附加到正在运行的进程,并在“监视”窗口和“即时”窗口中对表达式求值。 在调试器中,可以检查局部变量、使用断点、单步执行/输出/跳过语句、设置下一语句等。

有关特定于方案的调试信息,请参阅以下文章:

先决条件

  • 安装了支持 Python 工作负载的 Visual Studio。 有关详细信息,请参阅 在 Visual Studio中安装 Python 支持。

  • 要与调试器一起使用的 Python 代码。

在有项目或无项目的情况下调试代码

如果要控制 Python 环境和参数,请先为代码创建项目。 你可以使用“从现有 Python 代码”项目模板来创建项目。 有关详细信息,请参阅 从现有 Python 代码文件创建项目。

但是,不需要 Visual Studio 中的项目或解决方案文件来调试 Python 代码。 若要调试独立 Python 文件中的代码,请在 Visual Studio 中打开文件,然后选择 “调试”>“开始调试”。 Visual Studio 使用全局默认环境启动脚本,且无参数。 然后,你对代码具有完全调试支持。 有关详细信息,请参阅 Python 环境

探索基本调试

基本调试工作流涉及设置断点、单步执行代码、检查值和处理异常。 可以通过选择 调试>启动调试 或使用 F5 键盘快捷方式来启动调试会话。 对于一个项目,这些操作会使用项目的活动环境以及为“项目属性”指定的任何命令行参数或搜索路径来启动“启动文件”。 若要配置属性,请参阅 设置项目调试选项

设置项目启动文件

项目的启动文件会在“解决方案资源管理器”中以粗体显示。 可以选择用作启动文件的文件。

  • 若要将项目文件指定为启动文件,请右键单击该文件并选择 设置为启动项

在 Visual Studio 2017 版本 15.6 及更高版本中,如果未设置指定的启动文件,则会看到警报。 早期版本的 Visual Studio 可能会在运行 Python 解释器的情况下打开 输出 窗口,或者 输出 窗口短暂打开和关闭。

指定活动环境

如果使用的是项目文件,调试器始终从项目的活动 Python 环境开始。 可以更改当前活动环境。 有关详细信息,请参阅 为项目选择 Python 环境。

如果要调试独立的 Python 代码文件,Visual Studio 将使用全局默认环境启动脚本,且无参数。

设置断点

断点在标记点停止执行代码,以便可以检查程序状态。

对于使用其他编程语言的开发人员来说,Python 中的一些断点可能令人吃惊。 在 Python 中,整个文件都是可执行代码,因此 Python 在加载该文件以处理任何顶级类或函数定义时运行该文件。 如果设置了断点,你可能会发现调试器通过一个类声明从中间断开。 此行为正确,即使有时令人吃惊。

  • 若要设置断点,请在代码编辑器的左边距中选择,或右键单击代码行,然后选择 断点>插入断点。 在每个设置了断点的行上都会出现一个红点。

    展示断点在 Visual Studio 中代码文件左边距处如何显示的屏幕截图。

  • 若要删除断点,请选择红点或右键单击代码行,然后选择 断点>删除断点。 你还可以通过选择红点,然后选择“断点”>“禁用断点”来禁用断点。

    显示如何在 Visual Studio 中代码文件左边距中禁用断点的屏幕截图。

设置条件和操作

可以自定义触发断点的条件,例如仅在变量设置为特定值或值范围时中断。

  • 若要设置条件,请右键单击断点的红点,选择 条件。 “断点设置”对话框会打开。

    在对话框中,可以使用 Python 代码添加多个条件并创建条件表达式。 有关 Visual Studio 中此功能的完整详细信息,请参阅 断点条件

    显示如何选择在 Visual Studio 中为断点配置条件的选项的屏幕截图。

  • 还可以选择为断点设置“操作”。 可以创建一条消息以记录到“输出”窗口,还可选择指定自动继续执行

    显示如何在 Visual Studio 中为断点创建跟踪点操作的屏幕截图。

    记录消息会创建一个 跟踪点,该跟踪点不会直接向应用程序添加日志记录代码。

根据为断点配置条件和操作的方式,左边距中的红色图标会更改以指示设置。 你可能会看到点形状、时钟计时器或菱形。

逐行执行代码

当 Visual Studio 在断点停止代码执行时,可以使用多个命令逐步执行代码或运行代码块,然后再再次中断。 这些命令在 Visual Studio 的几个位置可用,包括 调试器 工具栏、调试 菜单、代码编辑器中的右键单击上下文菜单,以及通过键盘快捷方式。

下表总结了这些命令并提供键盘快捷方式:

命令 快捷键 描述
Stop Shift + F5 停止调试会话。
Restart Ctrl + Shift + F5 重启当前调试会话。
Continue F5 运行代码,直到到达下一个断点。
Step Into F11 运行下一个语句并停止。 如果下一个语句是对函数的调用,调试器将在调用函数的第一行处停止。
Step Over F10 运行下一个语句,包括调用函数(运行其所有代码)并应用任何返回值。 此命令允许你轻松跳过不需要调试的函数。
Step Out Shift+F11 运行代码,直到当前函数的末尾,然后逐步执行到调用语句。 当不需要调试当前函数的其余部分时,此命令非常有用。
Run to Cursor Ctrl+F10 运行代码,直到编辑器中的插入符号位置。 此命令允许你轻松跳过不需要调试的代码段。
设置下一个语句 Ctrl+Shift+F10 将代码中的当前运行点更改为插入符号的位置。 此命令允许你省略运行代码段,例如,当你知道代码出错或产生不需要的副作用时。
显示下一语句 Alt+Num+\ 返回到在代码中运行的下一个语句。 此命令可帮助你在代码中查找停止调试器的位置。

检查和修改值

在调试器中停止代码执行时,可以检查和修改变量的值。 还可以使用 监视 窗口来监控各个变量和自定义表达式。 有关详细信息,请参阅检查变量

  • 若要在调试期间使用 DataTips 功能查看值,请将鼠标悬停在编辑器中的任何变量上。 可以选择变量值来更改它:

    显示 Visual Studio 调试器中变量的数据提示值的屏幕截图。

  • 要使用“自动”窗口,请选择“调试”>“窗口”>“自动”。 此窗口包含接近当前语句的变量和表达式。 可以在值列中双击,或选择并输入 F2 来编辑该值:

    显示 Visual Studio 调试器中的“自动”窗口的屏幕截图。

    有关使用“自动”窗口的详细信息,请参阅在“自动变量”和“局部变量”窗口中检查变量

  • 要使用“局部变量”窗口,请选择“调试”>“窗口”>“局部变量”。 此窗口显示当前范围内的所有变量,可以再次对其进行编辑:

    显示 Visual Studio 调试器中“局部变量”窗口的屏幕截图。

    有关使用“局部变量”窗口的详细信息,请参阅在“自动变量”和“局部变量”窗口中检查变量

  • 要使用“监视”窗口,请选择“调试”>“窗口”>“监视”>监视 1-4。 此选项允许输入任意 Python 表达式并查看结果。 每个步骤都重新计算了表达式:

    显示 Visual Studio 调试器中的“监视”窗口的屏幕截图。

    有关使用“监视”窗口的详细信息,请参阅使用监视窗口和快速监视窗口对变量设置监视

  • 若要检查字符串值,请选择 条目右侧的 视图(放大镜)。 strunicodebytesbytearray 类型都可用于检查。

    视图 下拉菜单显示四个可视化选项:文本、HTML、XML 或 JSON。

    显示如何从 Visual Studio 调试器中的视图放大镜访问可视化工具的屏幕截图。

    选择可视化效果后,弹出对话框会根据所选类型显示未标记的字符串值。 你可以查看带有换行、滚动、语法突出显示以及树状视图的字符串。 这些可视化有助于调试涉及冗长复杂字符串的问题。

查看异常

如果在调试过程中程序发生错误,但你没有异常处理程序,调试器会在异常发生时中断:

显示 Visual Studio 调试器中未经处理的错误的异常弹出窗口的屏幕截图。

发生错误时,可以检查当前程序状态,包括调用堆栈。 然而,如果你逐行执行代码,调试过程会持续引发异常,直到该异常被处理或者你的程序退出。

  • 若要查看异常的扩展视图,请选择 调试>Windows>异常设置

    显示 Visual Studio 调试器中的“异常设置”窗口的屏幕截图。

    在“异常设置”窗口中,某个异常旁的复选框用于控制调试程序在该异常引发时是否始终中断。

  • 若要更频繁地中断特定异常,请在 异常设置 窗口中选中异常旁边的复选框。

  • 默认情况下,大多数异常在源代码中找不到异常处理程序时会中断。 若要更改此行为,请右键单击任何异常并修改“在用户代码中未经处理时继续”选项。 若要减少因异常而中断的次数,请取消选中此选项。

  • 若要配置 异常设置 窗口中未显示的异常,请选择 添加(加号)。 输入要监视的异常的名称。 该名称必须与异常的完整名称匹配。

配置项目调试选项

默认情况下,调试器使用标准 Python 启动器、无命令行参数和其他特殊路径或条件启动程序。 可以通过设置调试属性来配置 Python 项目的启动选项。

  • 若要访问项目的调试属性,请在 解决方案资源管理器中右键单击 Python 项目,选择 属性,然后选择“调试 ”选项卡

    显示 Visual Studio 调试器中的 Python 项目调试属性的屏幕截图。

以下各节介绍特定属性。

定义启动行为

下表列出了 启动模式 属性的可能值。 使用此属性定义调试器的启动行为。

价值 描述
标准 Python 启动器 使用以可移植 Python 编写的调试代码,与 CPython、IronPython 和变体(如 Stackless Python)兼容。 此选项为调试纯 Python 代码提供最佳体验。 附加到正在运行的 python.exe 进程时,将使用此属性中指定的启动器。 此启动器还提供适用于 CPython 的 混合模式调试,使您可以在 C/C++ 代码和 Python 代码之间无缝调试。
网络启动器 在启动时启动默认浏览器并启用模板调试。 有关详细信息,请参阅 Web 模板调试 部分。
Django Web 启动器 实现在 Django 环境下与 Web 启动程序的 属性相同的行为。 仅出于向后兼容性的目的使用此选项。
IronPython (.NET) 启动器 使用只适用于 IronPython 的 .NET 调试器,同时允许在任何 .NET 语言项目(包括 C# 和 Visual Basic)之间单步执行。 如果附加到托管 IronPython 的正在运行的 .NET 进程,将使用此启动器。

定义运行行为

下表描述了可以设置为为调试器配置运行行为的属性。

财产 描述
搜索路径 指定 Visual Studio 用于项目的文件和文件夹搜索路径。 这些值与解决方案资源管理器中项目的搜索路径节点中显示的项匹配。 虽然您可以在此对话框中指定搜索路径,但使用 解决方案资源管理器更加方便,因为您可以浏览文件夹并自动将路径转换为相对形式。
脚本参数 定义要添加到 Visual Studio 用于启动脚本的命令的参数,并在脚本的文件名之后显示。 值中列出的第一项在脚本中可作为 sys.argv[1] 使用,第二项可作为 sys.argv[2] 使用,依此类推。
解释器参数 列出在脚本名称之前添加到启动器命令行的参数。 常见参数 -W ... 控制警告,-O 稍微优化程序,并 -u 使用无缓冲区 IO。 IronPython 用户可能会使用此字段传递 -X 选项,例如 -X:Frames-X:MTA
解释器路径 标识解释器路径以替代与当前环境关联的路径。 该值对于使用非标准解释器启动脚本可能很有用。
环境变量 使用此属性可添加表单 <NAME>=\<VALUE>的条目。 Visual Studio 最后应用此属性值,该值会覆盖任何现有的全局环境变量,并且是在根据“搜索路径”设置设置好 PYTHONPATH 之后进行应用。 因此,此设置可用于手动替代任何其他变量。

使用交互式窗口

调试会话期间可以使用两个 交互式 窗口:标准 Visual Studio 即时 窗口和 Python 调试交互式 窗口。

打开“即时”窗口

可以使用标准的 Visual Studio 即时 窗口快速评估 Python 表达式,并在正在运行的程序中检查或分配变量。 有关详细信息,请参阅 即时窗口

  • 要打开“即时”窗口,请选择“调试”>“窗口”>“即时”。 还可以使用键盘快捷方式 Ctrl+Alt+I

打开“调试交互”窗口

Python 调试交互式 窗口提供了丰富的环境,其中包含调试时可用的完整 交互式 REPL 体验,包括编写和运行代码。 此窗口会自动连接到使用标准 Python 启动器在调试器中启动的任何进程,包括通过连接“调试”>“附加到进程”附加的进程。 但是,使用混合模式 C/C++调试时,此窗口不可用。

  • 要使用“调试交互式”窗口,选择“调试”>“窗口”>“Python 调试交互式” (Shift+Alt+I)。

    显示如何使用 Visual Studio 中的 Python 调试交互窗口的屏幕截图。

除了 标准 REPL 命令之外,调试交互式 窗口还支持特殊的元命令,如下表所述:

命令 描述
$continue$cont$c 从当前语句开始运行程序。
$down$d 在堆栈跟踪中向下移动当前帧一级。
$frame 显示当前帧 ID。
$frame 将当前帧切换到指定的帧 ID。
- 需要 <帧 ID> 参数。
$load 从文件加载命令并执行,直到完成。
$proc 显示当前进程 ID。
$proc 将当前进程切换到指定的进程 ID。
- 需要 <进程 ID> 参数。
$procs 列出当前正在调试的进程。
$stepin$step$s 如果可能,请单步执行下一个函数调用。
$stepout$return$r 跳出当前函数。
$stepover$until$unt 跳过下一个函数调用。
$thread 显示当前线程 ID。
$thread 将当前线程切换到指定的线程 ID。
- 需要 <线程 ID> 参数。
$threads 列出当前正在调试的线程。
$up$u 在堆栈跟踪中向上移动当前帧一级。
$where$w$bt 列出当前线程的帧。

标准调试器窗口(如 进程线程调用堆栈)不会与调试交互式 窗口 同步。 如果更改 调试交互式 窗口中的活动进程、线程或帧,则其他调试器窗口不会受到影响。 同样,在其他调试器窗口中更改活动进程、线程或帧不会影响“调试交互式”窗口。

使用旧版调试器

根据环境配置,可能需要使用旧版调试器:

  • Visual Studio 2017 版本 15.7 及更低版本(Python 2.6、3.1 到 3.4 或 IronPython)
  • Visual Studio 2019 版本 16.5 及更高版本(Python 2.6、3.1 到 3.4 或 IronPython)
  • ptvsd 3.x 和早期 4.x 版本

旧版调试器是 Visual Studio 2017 版本 15.7 及更早版本中的默认值。

  • 若要使用旧版调试器,请选择 工具>选项,展开 Python>调试 选项,然后选择 使用旧版调试器 选项。

支持较旧的 Visual Studio 或 Python 版本

Visual Studio 2017 版本 15.8 及更高版本使用基于 ptvsd 版本 4.1 及更高版本的调试器。 Visual Studio 2019 版本 16.5 及更高版本使用基于 debugpy 的调试器。 这两个版本的调试器与 Python 2.7 或 Python 3.5 及更高版本兼容。

如果运行的是 Visual Studio 的其中一个版本,但使用的是 Python 2.6、3.1 到 3.4 或 IronPython,Visual Studio 会显示错误,调试器不支持此 Python 环境

调试器错误消息“调试器不支持此 Python 环境的屏幕截图”。

当 Visual Studio 报告此环境错误时,必须使用旧版调试器。

支持较旧的 ptvsd 版本

如果在当前环境中使用旧版 ptvsd(例如早期 4.0.x 版本或远程调试所需的 3.x 版本),Visual Studio 可能会显示错误或警告。

如果环境使用 ptvsd 3.x,Visual Studio 会显示错误,调试器包无法加载

调试器错误消息“无法加载调试器包”的屏幕截图。

使用早期 4.x 版本的 ptvsd 时,将显示警告 调试器包已过时

调试器警告消息“调试器包已过时”的屏幕截图。

当 Visual Studio 报告这些环境错误时,必须使用旧版调试器。

重要

尽管可以选择忽略某些版本的 ptvsd 警告,但 Visual Studio 可能无法正常工作。

管理 ptvsd 安装

按照以下步骤管理 ptvsd 安装:

  1. 在“Python 环境”窗口中,转到“”选项卡。

  2. 在搜索框中输入 ptvsd,并检查已安装的 ptvsd 版本:

    显示如何在 Python 环境窗口中检查 ptvsd 版本的屏幕截图。

  3. 如果版本低于 4.1.1a9(与 Visual Studio 捆绑的版本),请选择包右侧的 X 以卸载旧版本。 然后,Visual Studio 使用其捆绑版本。 (也可以使用 pip uninstall ptvsd 命令从 PowerShell 中卸载。

  4. 或者,可以按照 排查调试方案 部分中的说明,将 ptvsd 包更新到其最新版本。

故障排除调试场景

以下方案描述了调试配置的其他故障排除选项。

为 Visual Studio 2019 升级 ptvsd

如果 Visual Studio 2019 版本 16.4 及更低版本中的调试器出现问题,请先升级调试器版本,如下所示:

  1. 在“Python 环境”窗口中,转到“”选项卡。

  2. 在搜索框中输入 ptvsd --upgrade,然后选择 执行命令:pip install ptvsd --upgrade。 (还可以从 PowerShell 使用相同的命令。

    显示如何在 Python 环境窗口中选择 ptvsd 升级命令的屏幕截图。

    如果此问题一再出现,请在 PTVS GitHub 存储库中提交问题。

    说明

    对于 Visual Studio 2019 版本 16.5 及更高版本,debugpy 是 Visual Studio Python 工作负载的一部分,并与 Visual Studio 一起更新。

启用调试器日志记录

在调查调试器问题的过程中,Microsoft可能会要求启用和收集调试器日志以帮助诊断。

若要在当前 Visual Studio 会话中启用调试,请按照以下步骤操作:

  1. 通过选择“视图”>“其他窗口”>“命令窗口”,在 Visual Studio 中打开一个命令窗口。

  2. 输入以下命令:

    DebugAdapterHost.Logging /On /OutputWindow
    
  3. 开始调试,并按照步骤操作以重现您遇到的问题。 在此期间,调试日志将显示在 调试适配器主机日志下的 输出 窗口中。 然后,可以从该窗口中复制日志并粘贴到 GitHub 问题、电子邮件等中。

    显示 Visual Studio 的“输出”窗口中调试器日志记录输出的屏幕截图。

  4. 如果 Visual Studio 停止响应,否则无法访问 输出 窗口,请重启 Visual Studio,打开命令窗口,然后输入以下命令:

    DebugAdapterHost.Logging /On
    
  5. 开始调试并再次重现问题。 调试器日志位于 %temp%\DebugAdapterHostLog.txt中。