VS Code 中的 Python 调试

Python 扩展支持通过 Python Debugger 扩展进行多种 Python 应用的调试。关于基础调试的简短演示,请参见教程——配置并运行调试器。也可以参考Flask教程。这两个教程都展示了核心技能,比如设置断点和逐步执行代码。

关于一般调试功能,比如检查变量、设置断点以及其他非依赖语言的活动,请回顾VS Code调试

本文主要讨论 Python 专用的调试配置,包括特定应用类型和远程调试所需的步骤。

Python 调试器扩展

Python 调试器扩展会与 VS Code 的 Python 扩展一起自动安装。它为多种类型的 Python 应用提供了调试功能,包括脚本、网页应用、远程进程等。

要验证是否安装,打开扩展视图(⇧⌘X(Windows,Linux Ctrl+Shift+X),搜索@installed Python 调试器.你应该能在结果中看到 Python Debugger 扩展。

Python 调试器扩展在 VS Code 的已安装扩展视图中展示。

你可以参考扩展的 README 页面,了解支持的 Python 版本。

初始化配置

配置驱动 VS Code 在调试会话中的行为。配置定义在launch.json存储在.vscode在你的工作区里。

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

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

跑动图标

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

调试工具栏设置命令

生成一个launch.json带有Python配置的文件,请执行以下步骤:

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

  2. 从调试器选项列表中选择“Python Debugger”。

  3. 命令面板会打开一个配置菜单,允许你选择我们 Python 项目文件中想要使用的调试配置类型。如果你想调试单个 Python 脚本,可以在出现的“选择调试配置文件”菜单中选择 Python 文件

    Python 调试器配置选项列表

    注意:在没有配置的情况下,通过调试面板、F5“运行>开始调试”启动调试会话也会弹出调试配置菜单,但不会创建launch.json档案。

  4. Python 调试器扩展随后创建并打开launch.json包含基于你之前选择的预定义配置的文件,在这里是 Python 文件。你可以修改配置(比如添加参数),也可以添加自定义配置。

    Configuration json

关于配置属性的细节,本文后面的标准配置和选项部分将详细介绍。其他配置也在本文“调试特定应用类型”一栏中有所描述。

其他配置

默认情况下,VS Code 只显示 Python 调试器扩展提供的最常见的配置。你可以选择其他配置来包含在launch.json通过使用列表中显示的添加配置命令和launch.json编辑。使用该命令时,VS Code 会提示你列出所有可用配置(请务必选择 Python 选项):

添加新的 Python 调试配置

使用Process ID One选择连接,结果如下:添加了一个配置

有关所有这些配置的详细信息,请参见“调试特定应用类型”。

调试时,状态栏显示当前配置和当前调试解释器。选择配置会弹出一个列表,您可以从中选择不同的配置:

调试状态栏

默认情况下,调试器使用与你工作区所选的解释器相同,就像 Python VS Code 扩展的其他功能一样。要专门使用不同的解释器进行调试,可以设置派森launch.json用于相应的调试器配置。或者,使用状态栏上的 Python 解释器指示器来选择另一个。

基础调试

如果你只想调试 Python 脚本,最简单的方法是在编辑器中点击运行按钮旁的下箭头,然后选择 Python Debugger: Debug Python 文件

编辑器右上角的调试按钮

如果你想用 Flask、Django 或 FastAPI 调试一个网页应用,Python Debugger 扩展可以通过运行和调试视图的“显示所有自动调试配置”选项,根据你的项目结构动态生成调试配置。

运行视图中显示所有自动调试配置选项

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

运行调试器

当没有设置任何配置时,系统会给你一份调试选项列表。在这里,你可以选择合适的选项来快速调试你的代码。

两种常见选择是使用 Python 文件配置来运行当前打开的 Python 文件,或者使用 Attach using Process ID 配置将调试器附加到已经运行中的进程上。

有关创建和使用调试配置的信息,请参见初始化配置附加配置部分。添加配置后,可以从下拉列表中选择,并通过开始调试按钮(F5)开始。

运行和调试视图中的开始调试按钮

命令行调试

如果调试安装在你的Python环境中。

安装调试程序

你可以用以下方式安装调试Python -m pip install --upgrade debugpy进入你的Python环境。

提示

虽然使用虚拟环境并非必需,但这是推荐的最佳实践。你可以在 VS Code 中创建虚拟环境,方法是打开命令面板(Windows,Linux 的 Ctrl+Shift+P并运行 Python: Create Environment 命令,或在环境管理器视图中点击 + 键。

命令行语法

调试器的命令行语法如下:

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)启动调试器,并使用以下语法编写脚本。本示例假设脚本是长运行的,省略了——等待客户标记,意味着脚本不会等待客户端附加。

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

然后你可以通过以下配置从VS Code Python Debugger扩展中附加到这个配置。

{
  "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.1本地主持你是在打开一个端口,允许任何机器访问,这存在安全风险。在进行远程调试时,你应确保采取适当的安全措施,比如使用 SSH 隧道。

命令行选项

旗帜 选项 描述
——倾听——连接 [<主持人>:]<端口> 必须。指定调试适配器服务器等待入线连接(--listen)或连接等待入线连接的客户端(--connect)的主机地址和端口。这与VS Code调试配置中使用的地址相同。默认情况下,主机地址为localhost (127.0.0.1).
——等待客户 没有 可选。规定代码在与调试服务器连接之前不应运行。这个设置允许你从代码的第一行开始调试。
--日志 <路径> 可选。指定通往现有目录的路径以保存日志。
--log-to-stderr 没有 可选。使 debugpy 能够直接将日志写入 stderr。
——皮德 <皮德> 可选。指定一个已经运行中的进程,用于注入调试服务器。
--配置-<名> <价值> 可选。设置一个调试属性,必须在客户端连接前让调试服务器知道。这些属性可以直接用于发射配置,但必须以这种方式设置以实现“连接”配置。例如,如果你不希望调试服务器自动注入你所关联进程创建的子进程,可以使用--configure-subProcess false.

[<啊>]可以用来将命令行参数传递给正在启动的应用。

通过网络连接连接进行调试

本地脚本调试

有时你可能需要调试一个由本地进程调用的 Python 脚本。例如,你可能在调试一个运行不同Python脚本的Web服务器,用于特定的处理任务。在这种情况下,你需要在脚本启动后将 VS Code 调试器附加到脚本上:

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

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

    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')
    
  3. 使用“终端:创建新终端”打开终端,激活脚本所选环境。

  4. 在终端安装debugpy包

  5. 在终端中,用脚本启动 Python,例如,Python3 myscript.py.你应该会看到代码中包含的“等待调试器附加”消息,脚本会在debugpy.wait_for_client()叫。

  6. 切换到运行和调试视图(⇧⌘D(Windows,Linux Ctrl+Shift+D),从调试器下拉菜单中选择相应配置,然后启动调试器。

  7. 调试器应该会在debugpy.breakpoint()调用,之后你就可以正常使用调试器了。你也可以选择用界面设置脚本代码中的其他断点,而不是用debugpy.breakpoint().

使用SSH进行远程脚本调试

远程调试允许你在远程计算机上运行程序时,在VS Code本地逐步作程序。无需在远程计算机上安装 VS Code。为了增加安全性,你可能需要在调试时使用安全连接,比如SSH连接到远程计算机。

注意:在Windows电脑上,您可能需要安装Windows 10 OpenSSH,才能实现指挥部。

以下步骤概述了建立SSH隧道的一般流程。SSH隧道让你能像直接在远程设备上一样在本地机器上工作,比打开端口供公众访问更安全。

在远程电脑上:

  1. 通过打开sshd_config配置文件(可在下文找到)/等等/嘘/在Linux及以下平台%programfiles(x86)%/openssh 等在 Windows 上),并添加或修改以下设置:

    AllowTcpForwarding yes
    

    注意:允许Tcp转发的默认是“是”,所以你可能不需要更改。

  2. 如果你需要添加或修改允许Tcp转发,重启SSH服务器。在Linux/macOS上运行Sudo 服务 SSH 重启;在Windows上运行services.msc, 选择 OpenSSH 或在服务列表中,选择重新开始

在本地电脑上:

  1. 通过运行创建SSH隧道ssh -2 -L sourceport:localhost:destinationport -i 身份文件 user@remoteaddress,使用选定的端口目的地港以及相应的用户名和远程计算机的IP地址user@remoteaddress.例如,要在IP地址1.2.3.4上使用端口5678,命令为ssh -2 -L 5678:localhost:5678 -i 身份文件 user@1.2.3.4.你可以用-我旗帜。

  2. 确认你能在 SSH 会话中看到提示。

  3. 在你的 VS Code 工作区里,创建一个远程调试的配置,在你的launch.json文件,将端口设置为与命令和主机本地主持.你用本地主持这里是因为你设置了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隧道已经建立好,连接到远程计算机,你可以开始调试了。

  1. 两台电脑:确保源代码完全相同。

  2. 两台电脑:安装调试程序

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

    1. 在源代码中,添加以下几行,替换地址与远程计算机的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()
      

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

    2. 通过调试程序启动远程进程,例如:

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

      这开始了包裹我的项目使用Python3,其中远程计算机的私有IP地址为1.2.3.4以及在港口监听5678(你也可以通过指定文件路径来启动远程 Python 进程,而不是用-m,例如./hello.py).

  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()
    
  5. 本地电脑:切换到 VS Code 中的运行和调试视图(⇧⌘D(Windows,Linux Ctrl+Shift+D),选择 Python 调试器:附加配置

  6. 本地计算机:在代码中设置一个断点,开始调试。

  7. 本地电脑:使用修改后的 Python 调试器启动 VS Code 调试器:附加配置和开始调试按钮。VS Code 应该在你本地设置的断点处停止,这样你就可以逐步处理代码、检查变量,并执行所有其他调试作。你在调试控制台输入的表达式也会在远程计算机上运行。

    文本输出到标准,来自印刷声明,显示在两台电脑上。然而,其他输出,如来自 matplotlib 等软件包的图形图,仅出现在远程计算机上。

  8. 在远程调试过程中,调试工具栏如下所示:

    远程调试时的调试工具栏

    在这个工具栏上,断开按钮(⇧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,这些配置不包含在标准配置中。

提示:在项目中,创建一个运行特定启动文件的配置通常很有帮助。比如,如果你想总是启动startup.py附有论证——1593号端口启动调试器时,创建如下配置条目:

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

名称

提供在VS Code下拉列表中出现的调试配置名称。

类型

识别应使用的调试器类型;留下此集合为调试用于调试 Python 代码。

请求

指定了调试开始的模式:

  • 发射: 在指定文件上启动调试器节目
  • 附着:将调试器附加到已运行的进程上。请参见远程调试示例。

节目

提供 Python 程序入口模块(启动文件)的完整合格路径。价值${file}通常用于默认配置,使用编辑器中当前激活的文件。通过指定特定的启动文件,无论打开哪些文件,你都能确保启动程序时使用相同的入口点。例如:

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

你也可以依赖工作区根的相对路径。例如,如果根是/用户/我/项目/我的项目然后你可以用以下例子:

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

模块

提供指定待调试模块名称的能力,类似于-m在命令行执行时,参数。更多信息请参见 Python.org

派森

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

如果未指定,该设置默认为你工作区选择的解释器,这等同于使用该值${command:python.interpreterPath}.要使用不同的解释器,请在派森调试配置的属性。

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

如果你需要把参数传递给 Python 解释器,可以用pythonArgs财产。

pythonArgs

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

args

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

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

如果你想每次调试都提供不同的参数,可以设置args“${command:pickArgs}”.每次启动调试会话时,都会提示你输入参数。

注意:在方式上是有区别的“${command:pickArgs}”以及[“${command:pickArgs}”]被解析,特别注意 的使用。作为数组,所有参数作为单一字符串传递,若无括号,每个参数作为独立字符串传递。[]

停止进入

当设置为确实如此,会在被调试程序的第一行就破坏调试器。如果省略(默认值)或设置为错误调试器将程序运行到第一个断点。

控制台

指定程序输出如何显示,只要默认值为重定向输出没有被修改。

价值 输出显示
“内部控制台” VS Code 调试控制台。如果重定向输出设置为 False,则不显示输出。
“integratedTerminal”(默认) VS Code 集成终端。如果重定向输出设置为 True,输出也会显示在调试控制台中。
“外部终端” 独立的控制台窗口。如果重定向输出设置为 True,输出也会显示在调试控制台中。

目的

配置“运行”按钮有多种方式,包括目的选项。将选项设置为调试-测试定义了在 VS Code 中调试测试时应使用该配置。 然而,将选项设置为终端调试,定义该配置仅在访问编辑器右上角的“运行 Python 文件”按钮时使用(无论该按钮提供的“运行 Python 文件”还是调试 Python 文件选项“)。:该目的选项不能通过F5启动调试器,也不能通过运行>开始调试

自动装填

允许在调试器执行达到断点后对代码进行修改时自动重新加载调试器。启用此功能集{“enable”: true}如下代码所示。

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

注意:当调试器执行重载时,导入时运行的代码可能会再次执行。为了避免这种情况,尽量只在模块中使用导入、常量和定义,把所有代码放进函数里。或者,你也可以使用如果 __name__==“__main__”支票。

子进程

指定是否启用子进程调试。默认错误,设为确实如此去促成。更多信息请参见多目标调试。

慢性消耗病

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

举个例子,比如${workspaceFolder}包含一个py_code包含以下内容的文件夹app.py,以及一个数据包含以下内容的文件夹salaries.csv.如果你启动调试器py_code/app.py那么,数据文件的相对路径会根据 的值变化慢性消耗病:

慢性消耗病 数据文件的相对路径
省略或${workspaceFolder} 数据/salaries.csv
${workspaceFolder}/py_code ../数据/salaries.csv
${workspaceFolder}/data salaries.csv

重定向输出

当设置为确实如此(internalConsole 的默认),会导致调试器将程序中的所有输出输出输出到 VS Code 调试输出窗口中。如果设置为错误(这是integratedTerminal和externalTerminal的默认),程序输出不会显示在调试器的输出窗口中。

使用时通常会关闭该选项“控制台”:“integratedTerminal”“console”:“externalTerminal”因为在调试控制台里不需要复制输出。

justMyCode

省略或设置为确实如此(默认情况下),仅限于用户编写的代码进行调试。设置为错误同时也支持对标准库函数的调试。

姜戈

当设置为确实如此激活 Django 网络框架特有的调试功能。

须藤

当设置为确实如此并用于“console”:“externalTerminal”,允许调试需要高程的应用程序。必须使用外部控制台来获取密码。

金字塔

当设置为确实如此,确保金字塔应用启动时以必要的保护指挥.

环境

为调试器过程设置除系统环境变量外的可选环境变量,这些变量由调试器继承。这些变量的值必须以字符串形式输入。

envFile

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

金特

如果设置为确实如此,支持对 gevent 猴子补丁代码进行调试。

金子

当设置为确实如此激活 Jinja 模板框架特有的调试功能。

断点与对数点

Python Debugger 扩展支持断日志点以进行代码调试。关于基础调试和断点的简要教程,请参见教程——配置并运行调试器

条件断点

断点也可以根据表达式、命中次数或两者结合触发。Python 调试器扩展支持整数命中计数,此外还有前置于 ==、>、>=、<、<= 和 % 运算符的整数。例如,你可以通过设置命中计数>5更多信息请参见主VS Code调试文章中的条件断点

代码中调用断点

在你的 Python 代码中,你可以调用debugpy.breakpoint()在调试会话中任何你想暂停调试器的时候都可以。

断点验证

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

调试特定应用类型

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

配置 描述
附上 参见上一节的远程调试
姜戈 具体说明“program”: “${workspaceFolder}/manage.py”,“ARGS”: [“runserver”].还补充了“Django”:确实如此以支持对 Django HTML 模板的调试。
烧瓶 详见下文Flask调试
吉盖特 补充“Gevent”:真到标准集成端子配置。
金字塔 移除节目补充道“args”: [“${workspaceFolder}/development.ini”]补充道“神者”:确实如此用于支持模板调试,以及添加“金字塔”:确实如此以确保该项目能够以必要的保护指挥.

远程调试和 Google 应用引擎也需要具体步骤。有关调试测试的详细信息,请参见测试。

要调试需要管理员权限的应用,请“console”:“externalTerminal”以及“sudo”:“真”.

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”].该“模块”:“瓶子”使用属性代替节目.(你可能会看到“FLASK_APP”:“${workspaceFolder}/app.py”环境在这种情况下,修改配置以仅指文件名。否则,你可能会看到“无法导入模块C”错误,其中C是驱动器代号。)

“神者”:确实如此设置还支持对 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
},

故障排除

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

  • 请通过打开扩展视图(⇧⌘X(Windows,Linux Ctrl+Shift+X)并搜索@installed Python 调试器.

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

    调试时排查错误的Python解释器

  • 你已经“类型”设置为废弃值“Python”在你的launch.json文件:替换“Python”其中“调试”而是用 Python Debugger 扩展来作。

  • 观察窗口中存在无效表达式:清除观察窗口中的所有表达式并重启调试器。

  • 如果你正在使用使用原生线程 API(例如 Win32)的多线程应用创建线程函数而非 Python 线程 API),目前必须在你想调试的文件顶部包含以下源代码:

    import debugpy
    debugpy.debug_this_thread()
    
  • 如果你使用Linux系统,尝试对任何运行中的进程应用调试器时,可能会收到“超时”错误信息。为了防止这种情况,你可以临时运行以下命令:

    echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
    

下一步

  • Python 环境——控制用于编辑和调试的 Python 解释器。
  • 测试——配置测试环境,并发现、运行和调试测试。
  • 设置参考——探索VS Code中所有与Python相关的设置。
  • 通用调试——了解VS Code的调试功能。