添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

VS Code 中的 Python 调试

Python 扩展通过 Python Debugger 扩展 支持调试多种类型的 Python 应用程序。有关基本调试的简要演练,请参阅 教程 - 配置和运行调试器 。另请参阅 Flask 教程 。这两个教程都演示了设置断点和单步执行代码等核心技能。

对于与语言无关的通用调试功能(例如检查变量、设置断点和其他活动),请查看 VS Code 调试

本文主要介绍 Python 特定的调试 *配置*,包括特定应用程序类型和远程调试的必要步骤。

Python Debugger 扩展

Python Debugger 扩展 会与 VS Code 的 Python 扩展 一起自动安装。它提供了与 debugpy 结合使用的调试功能,适用于多种类型的 Python 应用程序,包括脚本、Web 应用程序、远程进程等等。

要验证它是否已安装,请打开 **扩展** 视图( ⇧⌘X (Windows、Linux Ctrl+Shift+X )并搜索 @installed python debugger 。你应该在结果中看到 Python Debugger 扩展。

你可以参考扩展的 README 页面以获取有关支持的 Python 版本的信息。

初始化配置

配置会驱动 VS Code 在调试会话期间的行为。配置在 `launch.json` 文件中定义,该文件存储在工作区中的 `.vscode` 文件夹中。

**注意**:要更改调试配置,你的代码必须存储在文件夹中。

要初始化调试配置,请先在侧边栏中选择 **运行** 视图

如果你还没有定义任何配置,你将看到一个 **运行和调试** 按钮和一个创建配置(launch.json)文件的链接

要使用 Python 配置生成 `launch.json` 文件,请执行以下步骤

选择 **创建 launch.json 文件** 链接(如上图中所示),或使用 **运行** > **打开配置** 菜单命令。

从调试器选项列表中选择 **Python Debugger**。

一个配置菜单将从命令面板打开,允许你为 Python 项目文件选择要使用的调试配置类型。如果你想调试单个 Python 脚本,请在出现的 **选择调试配置** 菜单中选择 **Python 文件**。

配置属性的详细信息将在本文后面的 标准配置和选项 部分中介绍。本文后面的 调试特定应用程序类型 部分还介绍了其他配置。

默认情况下,VS Code 只显示 Python Debugger 扩展提供的最常见的配置。你可以使用列表和 `launch.json` 编辑器中显示的 **添加配置** 命令选择要包含在 `launch.json` 中的其他配置。当你使用该命令时,VS Code 会提示你列出所有可用配置(请确保选择 **Python** 选项)。

选择 **使用进程 ID 附加** 选项将产生以下结果: 已添加配置

有关所有这些配置的详细信息,请参阅 调试特定应用程序类型

在调试期间,状态栏将显示当前配置和当前调试解释器。选择配置会调出一个列表,你可以从中选择不同的配置

默认情况下,调试器将使用与 VS Code 的 Python 扩展其他功能相同的解释器。要专门使用不同的解释器进行调试,请在 `launch.json` 中为适用的调试器配置设置 `python` 的值。或者,使用状态栏上的 Python 解释器指示器选择其他解释器。

如果你只对调试 Python 脚本感兴趣,最简单的方法是选择编辑器中运行按钮旁边的向下箭头,然后选择 **Python Debugger: 调试 Python 文件**。

如果你想调试使用 Flask、Django 或 FastAPI 的 Web 应用程序,Python Debugger 扩展将在 **显示所有自动调试配置** 选项下(通过 **运行和调试** 视图)根据你的项目结构提供动态创建的调试配置。

但是,如果你想调试其他类型的应用程序,你可以通过 **运行** 视图单击 **运行和调试** 按钮启动调试器。

如果尚未设置任何配置,你将看到一个调试选项列表。在这里,你可以选择合适的选项来快速调试你的代码。

两个常见选项是使用 **Python 文件** 配置来运行当前打开的 Python 文件,或者使用 **使用进程 ID 附加** 配置来将调试器附加到正在运行的进程。

有关创建和使用调试配置的信息,请参阅 初始化配置 其他配置 部分。添加配置后,可以从下拉列表中选择它,并使用 **开始调试** 按钮( F5 )启动它。

命令行调试

如果在 Python 环境中安装了 `debugpy`,也可以从命令行运行调试器。

安装 debugpy

你可以使用 `python -m pip install --upgrade debugpy` 将 debugpy 安装到你的 Python 环境中。

**提示**:虽然使用虚拟环境不是必需的,但它是一个推荐的最佳实践。你可以在 VS Code 中创建一个虚拟环境,方法是打开命令面板( ⇧⌘P (Windows、Linux Ctrl+Shift+P )并运行 **Python: 创建虚拟环境** 命令( )。

命令行语法

调试器命令行语法如下所示

python -m debugpy
    --listen | --connect
    [<host>:]<port>
    [--wait-for-client]
    [--configure-<name> <value>]...
    [--log-to <path>] [--log-to-stderr]
    <filename> | -m <module> | -c <code> | --pid <pid>
    [<arg>]...

从命令行,您可以使用以下语法使用指定端口(5678)和脚本启动调试器。此示例假定脚本是长时间运行的,并省略了--wait-for-client标志,这意味着脚本不会等待客户端连接。

python -m debugpy --listen 5678 ./myscript.py

然后,您将使用以下配置从 VS Code Python 调试器扩展进行连接。

"name": "Python Debugger: Attach", "type": "debugpy", "request": "attach", "connect": { "host": "localhost", "port": 5678

注意:指定主机对于监听是可选的,默认情况下使用 127.0.0.1。

如果您想调试远程代码或在 Docker 容器中运行的代码,您需要修改之前的 CLI 命令以指定主机。

python -m debugpy --listen 0.0.0.0:5678 ./myscript.py

然后,关联的配置文件将如下所示。

"name": "Attach", "type": "debugpy", "request": "attach", "connect": { "host": "remote-machine-name", // replace this with remote machine name "port": 5678

注意:请注意,当您指定除127.0.0.1localhost以外的主机值时,您正在打开一个端口以允许来自任何机器的访问,这会带来安全风险。您应该确保在进行远程调试时采取适当的安全预防措施,例如使用 SSH 隧道。

命令行选项

--listen--connect [<host>:]<port> 必需。指定调试适配器服务器等待传入连接(--listen)或连接到正在等待传入连接的客户端(--connect)的主机地址和端口。这与 VS Code 调试配置中使用的地址相同。默认情况下,主机地址为localhost (127.0.0.1)--wait-for-client 可选。指定代码在从调试服务器连接之前不运行。此设置允许您从代码的第一行进行调试。 --log-to 可选。指定一个路径到一个现有的目录以保存日志。 --log-to-stderr 可选。启用 debugpy 将日志直接写入 stderr。 --pid 可选。指定一个正在运行的进程,将调试服务器注入其中。 --configure-<name> <value> 可选。设置一个调试属性,该属性必须在客户端连接之前为调试服务器所知。这些属性可以在启动配置中直接使用,但必须以这种方式设置才能用于附加配置。例如,如果您不希望调试服务器自动将自身注入到您要附加到的进程创建的子进程中,请使用--configure-subProcess false

通过网络连接进行调试

本地脚本调试

在某些情况下,您可能需要调试由另一个进程在本地调用的 Python 脚本。例如,您可能正在调试一个 Web 服务器,该服务器为特定处理作业运行不同的 Python 脚本。在这种情况下,您需要在启动脚本后将 VS Code 调试器附加到该脚本。

运行 VS Code,打开包含脚本的文件夹或工作区,并为该工作区创建一个launch.json(如果还没有)。

在脚本代码中,添加以下内容并保存文件

import debugpy
# 5678 is the default attach port in the VS Code debug configurations. Unless a host and port are specified, host defaults to 127.0.0.1
debugpy.listen(5678)
print("Waiting for debugger attach")
debugpy.wait_for_client()
debugpy.breakpoint()
print('break on this line')

使用终端:创建新终端打开一个终端,它会激活脚本所选的环境。

在终端中,安装 debugpy 包

在终端中,使用脚本启动 Python,例如python3 myscript.py。您应该会看到代码中包含的“等待调试器附加”消息,并且脚本会在debugpy.wait_for_client()调用处停止。

切换到运行和调试视图(⇧⌘D(Windows、Linux Ctrl+Shift+D),从调试器下拉列表中选择适当的配置,然后启动调试器。

调试器应该在debugpy.breakpoint()调用处停止,从这一点开始,您可以正常使用调试器。您也可以选择使用 UI 在脚本代码中设置其他断点,而不是使用debugpy.breakpoint()

使用 SSH 的远程脚本调试

远程调试允许您在 VS Code 中本地逐步执行程序,同时该程序在远程计算机上运行。在远程计算机上安装 VS Code 不是必需的。为了提高安全性,您可能希望或需要在调试时使用安全连接(如 SSH)到远程计算机。

注意:在 Windows 计算机上,您可能需要安装Windows 10 OpenSSH才能拥有ssh命令。

以下步骤概述了设置 SSH 隧道的常规过程。SSH 隧道允许您在本地机器上工作,就像您直接在远程机器上工作一样,比为公共访问打开端口更安全。

在远程计算机上

通过打开sshd_config配置文件(在 Linux 上位于/etc/ssh/下,在 Windows 上位于%programfiles(x86)%/openssh/etc下)并添加或修改以下设置来启用端口转发

AllowTcpForwarding yes

注意AllowTcpForwarding的默认值为 yes,因此您可能不需要进行更改。

如果您必须添加或修改AllowTcpForwarding,请重新启动 SSH 服务器。在 Linux/macOS 上,运行sudo service ssh restart;在 Windows 上,运行services.msc,在服务列表中选择 OpenSSH 或sshd,然后选择重新启动

在本地计算机上

通过运行ssh -2 -L sourceport:localhost:destinationport -i identityfile user@remoteaddress创建 SSH 隧道,使用选定的端口作为destinationport,以及user@remoteaddress中适当的用户名和远程计算机的 IP 地址。例如,要使用 IP 地址 1.2.3.4 上的端口 5678,该命令将是ssh -2 -L 5678:localhost:5678 -i identityfile [email protected]。您可以使用-i标志指定身份文件的路径。

验证您是否可以在 SSH 会话中看到提示符。

在您的 VS Code 工作区中,在您的launch.json文件中创建一个用于远程调试的配置,将端口设置为与ssh命令中使用的端口匹配,并将主机设置为localhost。您在这里使用localhost,因为您已设置了 SSH 隧道。

"name": "Python Debugger: Attach", "type": "debugpy", "request": "attach", "port": 5678, "host": "localhost", "pathMappings": [ "localRoot": "${workspaceFolder}", // Maps C:\Users\user1\project1 "remoteRoot": "." // To current working directory ~/project1

现在已经设置了到远程计算机的 SSH 隧道,您可以开始调试了。

两台计算机:确保相同的源代码可用。

两台计算机:安装 debugpy

远程计算机:有两种方法可以指定如何连接到远程进程。

在源代码中,添加以下几行,将address替换为远程计算机的 IP 地址和端口号(这里仅用作说明,显示 IP 地址 1.2.3.4)。

import debugpy
# Allow other computers to attach to debugpy at this IP address and port.
debugpy.listen(('1.2.3.4', 5678))
# Pause the program until a remote debugger is attached
debugpy.wait_for_client()

listen中使用的 IP 地址应该是远程计算机的私有 IP 地址。然后,您可以正常启动程序,使其暂停直到调试器连接。

通过 debugpy 启动远程进程,例如

python3 -m debugpy --listen 1.2.3.4:5678 --wait-for-client -m myproject

这将使用python3启动包myproject,使用远程计算机的私有 IP 地址1.2.3.4并在端口5678上监听(您也可以通过指定文件路径而不是使用-m来启动远程 Python 进程,例如./hello.py)。

本地计算机:仅当您按照上述说明修改了远程计算机上的源代码时,然后在源代码中,添加已在远程计算机上添加的相同代码的注释掉的副本。添加这些行可以确保两台计算机上的源代码逐行匹配。

#import debugpy
# Allow other computers to attach to debugpy at this IP address and port.
#debugpy.listen(('1.2.3.4', 5678))
# Pause the program until a remote debugger is attached
#debugpy.wait_for_client()

本地计算机:切换到 VS Code 中的运行和调试视图(⇧⌘D(Windows、Linux Ctrl+Shift+D),选择Python 调试器:附加配置

本地计算机:在您想要开始调试的代码中设置断点。

本地计算机:使用修改后的Python 调试器:附加配置和启动调试按钮启动 VS Code 调试器。VS Code 应该在您本地设置的断点处停止,允许您逐步执行代码、检查变量并执行所有其他调试操作。您在调试控制台中输入的表达式也在远程计算机上运行。

文本输出到 stdout(例如来自print语句)出现在两台计算机上。但是,其他输出(例如来自像 matplotlib 这样的包的图形图)只出现在远程计算机上。

在远程调试期间,调试工具栏将显示如下

在这个工具栏上,断开连接按钮(⇧F5(Windows、Linux Shift+F5)停止调试器并允许远程程序运行完成。重启按钮(⇧⌘F5(Windows、Linux Ctrl+Shift+F5)在本地计算机上重启调试器,但不会重启远程程序。仅当您已重新启动远程程序并且需要重新连接调试器时,才使用重启按钮。

设置配置选项

当您第一次创建launch.json时,有两个标准配置,它们在集成终端(VS Code 内部)或外部终端(VS Code 外部)中运行编辑器中的活动文件

"configurations": [ "name": "Python Debugger: Current File (Integrated Terminal)", "type": "debugpy", "request": "launch", "program": "${file}", "console": "integratedTerminal" "name": "Python Debugger: Current File (External Terminal)", "type": "debugpy", "request": "launch", "program": "${file}", "console": "externalTerminal"

以下部分描述了具体设置。您还可以添加其他设置(例如args),这些设置未包含在标准配置中。

提示:在一个项目中,创建一个运行特定启动文件的配置通常很有帮助。例如,如果您希望在启动调试器时始终使用参数--port 1593启动startup.py,请创建一个配置条目,如下所示

"name": "Python Debugger: startup.py", "type": "debugpy", "request": "launch", "program": "${workspaceFolder}/startup.py", "args" : ["--port", "1593"]

提供调试配置的名称,该名称将显示在 VS Code 下拉列表中。

标识要使用的调试器类型;对于调试 Python 代码,请将此设置保留为debugpy

request

指定启动调试的模式

  • launch:在program中指定的文件上启动调试器
  • attach:将调试器附加到正在运行的进程。有关示例,请参阅远程调试
  • program

    提供 Python 程序入口模块(启动文件)的完全限定路径。值${file}(通常在默认配置中使用)使用编辑器中当前活动的

    "program": "/Users/Me/Projects/MyProject/src/event_handlers/__init__.py",
    

    您也可以依靠工作区根目录的相对路径。例如,如果根目录是/Users/Me/Projects/MyProject,那么您可以使用以下示例

    "program": "${workspaceFolder}/src/event_handlers/__init__.py",
    

    module

    提供指定要调试的模块名称的能力,类似于在命令行运行时使用-m参数。有关更多信息,请参阅Python.org

    python

    指向要用于调试的 Python 解释器的完整路径。

    如果未指定,此设置将默认为为您的工作区选择的解释器,这等效于使用值${command:python.interpreterPath}。要使用不同的解释器,请在调试配置的python属性中指定其路径。

    或者,您可以使用在每个平台上定义的自定义环境变量来包含要使用的 Python 解释器的完整路径,这样就不需要其他文件夹路径了。

    如果您需要向 Python 解释器传递参数,您可以使用pythonArgs属性。

    pythonArgs

    指定要使用语法"pythonArgs": ["<arg 1>", "<arg 2>",...]传递给 Python 解释器的参数。

    指定要传递给 Python 程序的参数。每个由空格分隔的参数字符串元素都应该包含在引号中,例如

    "args": ["--quiet", "--norepeat", "--port", "1593"],
    

    如果您想在每次调试运行时提供不同的参数,可以将 args 设置为 ${command:pickArgs}。这将提示您在每次启动调试会话时输入参数。

    stopOnEntry

    如果设置为 true,将在调试的程序的第一行处中断调试器。如果省略(默认值)或设置为 false,调试器将运行程序到第一个断点。

    console

    指定如何在不修改 redirectOutput 的默认值的情况下显示程序输出。

    Value 输出显示的位置

    purpose

    使用 purpose 选项有多种方法可以配置运行按钮。将选项设置为 debug-test 表示应在 VS Code 中调试测试时使用该配置。但是,将选项设置为 debug-in-terminal 表示该配置仅应在访问编辑器右上角的运行 Python 文件按钮时使用(无论按钮提供的运行 Python 文件调试 Python 文件选项是什么)。注意purpose 选项不能用于通过F5运行 > 启动调试来启动调试器。

    autoReload

    允许在调试器执行遇到断点后对代码进行更改时自动重新加载调试器。要启用此功能,请设置 {"enable": true},如以下代码所示。

    "name": "Python Debugger: Current File", "type": "debugpy", "request": "launch", "program": "${file}", "console": "integratedTerminal", "autoReload": { "enable": true

    注意:当调试器执行重新加载时,在导入时运行的代码可能会再次执行。为了避免这种情况,请尝试仅在您的模块中使用导入、常量和定义,并将所有代码放入函数中。或者,您也可以使用 if __name__=="__main__" 检查。

    subProcess

    指定是否启用子进程调试。默认为 false,设置为 true 以启用。有关更多信息,请参阅多目标调试

    指定调试器的当前工作目录,这是代码中使用的任何相对路径的基文件夹。如果省略,默认为 ${workspaceFolder}(在 VS Code 中打开的文件夹)。

    例如,假设 ${workspaceFolder} 包含一个包含 app.pypy_code 文件夹,以及一个包含 salaries.csvdata 文件夹。如果您在 py_code/app.py 上启动调试器,则数据文件相对于 cwd 的值将有所不同。

    数据文件相对于的路径

    redirectOutput

    如果设置为 true(internalConsole 的默认值),则会导致调试器将程序的所有输出打印到 VS Code 调试输出窗口。如果设置为 false(integratedTerminal 和 externalTerminal 的默认值),则程序输出不会显示在调试器输出窗口中。

    使用 "console": "integratedTerminal""console": "externalTerminal" 时通常会禁用此选项,因为不需要在调试控制台中重复输出。

    justMyCode

    如果省略或设置为 true(默认值),则将调试限制为仅用户编写的代码。设置为 false 以启用标准库函数的调试。

    django

    如果设置为 true,则会激活特定于 Django Web 框架的调试功能。

    如果设置为 true 并与 "console": "externalTerminal" 一起使用,则允许调试需要提升权限的应用程序。使用外部控制台是捕获密码所必需的。

    pyramid

    如果设置为 true,则确保 Pyramid 应用程序使用必要的 pserve 命令启动。

    为调试器进程设置可选环境变量,超出调试器始终继承的系统环境变量。这些变量的值必须以字符串形式输入。

    envFile

    包含环境变量定义的文件的可选路径。请参阅配置 Python 环境 - 环境变量定义文件

    gevent

    如果设置为 true,则会启用gevent 猴子修补的代码的调试。

    jinja

    如果设置为 true,则会激活特定于Jinja 模板引擎的调试功能。

    断点和日志点

    Python 调试器扩展支持断点日志点用于调试代码。有关基本调试和使用断点的简短演练,请参阅教程 - 配置和运行调试器

    断点也可以设置为根据表达式、命中次数或两者的组合来触发。Python 调试器扩展支持整数命中次数,以及以 ==、>、>=、<、<= 和 % 运算符开头的整数。例如,您可以将断点设置为在五次出现后触发,方法是将命中次数设置为 >5。有关更多信息,请参阅主要 VS Code 调试文章中的条件断点

    在代码中调用断点

    在 Python 代码中,您可以在调试会话期间要暂停调试器的任何位置调用 debugpy.breakpoint()

    Python 调试器扩展会自动检测设置在不可执行行上的断点,例如 pass 语句或多行语句的中间。在这种情况下,运行调试器会将断点移动到最近的有效行,以确保代码执行在该点停止。

    调试特定应用程序类型

    配置下拉菜单为通用应用程序类型提供了各种不同的选项

    Configuration Django 指定 "program": "${workspaceFolder}/manage.py""args": ["runserver"]。还会添加 "django": true 以启用 Django HTML 模板的调试。 Flask 请参阅下面的Flask 调试。 Gevent 在标准集成终端配置中添加 "gevent": true。 Pyramid 删除 program,添加 "args": ["${workspaceFolder}/development.ini"],添加 "jinja": true 以启用模板调试,并添加 "pyramid": true 以确保程序使用必要的 pserve 命令启动。

    远程调试和 Google App Engine 也需要采取具体的步骤。有关调试测试的详细信息,请参阅测试

    要调试需要管理员权限的应用程序,请使用 "console": "externalTerminal""sudo": "True"

    Flask 调试

    "name": "Python Debugger: Flask", "type": "debugpy", "request": "launch", "module": "flask", "env": { "FLASK_APP": "app.py" "args": [ "run", "--no-debugger" "jinja": true

    如您所见,此配置指定了 "env": {"FLASK_APP": "app.py"}"args": ["run", "--no-debugger"]"module": "flask" 属性用于代替 program。(您可能会在 env 属性中看到 "FLASK_APP": "${workspaceFolder}/app.py",在这种情况下,请修改配置以仅引用文件名。否则,您可能会看到 "Cannot import module C" 错误,其中 C 是一个驱动器号。)

    "jinja": true 设置还启用了 Flask 的默认 Jinja 模板引擎的调试。

    如果您想在开发模式下运行 Flask 的开发服务器,请使用以下配置

    "name": "Python Debugger: Flask (development mode)", "type": "debugpy", "request": "launch", "module": "flask", "env": { "FLASK_APP": "app.py", "FLASK_ENV": "development" "args": [ "run" "jinja": true

    调试器可能无法正常工作的原因有很多。有时调试控制台会显示特定原因,但主要原因如下

    确保Python 调试器扩展已在 VS Code 中安装并启用,方法是打开扩展视图(⇧⌘X(Windows、Linux Ctrl+Shift+X))并搜索 @installed python debugger

    Python 可执行文件的路径不正确:通过运行Python: 选择解释器命令并查看当前值来检查所选解释器的路径

    您在 launch.json 文件中将 "type" 设置为已弃用的值 "python":将 "python" 替换为 "debugpy" 以与 Python 调试器扩展一起使用。

    监视窗口中存在无效表达式:从监视窗口中清除所有表达式并重新启动调试器。

    如果您使用的是使用本机线程 API(例如 Win32 CreateThread 函数而不是 Python 线程 API)的多线程应用程序,目前有必要在要调试的任何文件的顶部包含以下源代码

    import debugpy
    debugpy.debug_this_thread()
    

    如果您使用的是Linux 系统,您可能会在尝试将调试器应用于任何正在运行的进程时收到 "timed out" 错误消息。要防止这种情况,您可以临时运行以下命令

    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    
  • Python 环境 - 控制用于编辑和调试的 Python 解释器。
  • 测试 - 配置测试环境并发现、运行和调试测试。
  • 设置参考 - 探索 VS Code 中所有 Python 相关设置。
  • 通用调试 - 了解 VS Code 的调试功能。
  •