debugpy 是微软开发的 Python 调试器,遵循 DAP 协议。VS Code 的 Python 扩展底层就是调用它——本地调试自动调用,远程调试与无 IDE 场景需手动配置。

核心特性

  • DAP 协议:统一 IDE 与调试器通信规范,兼容 VS Code、PyCharm 等
  • 远程调试:通过 socket 连接服务器/容器中的 Python 应用
  • 多进程支持:原生支持 multiprocessing
  • Jupyter 集成:可调试 Notebook 代码单元

何时需要显式使用

场景是否需要手动配置原因
VS Code 本地调试不需要Python 扩展自动调用
命令行直接调试需要无 IDE 介入
远程服务器调试需要需启动服务端等待连接
Docker 容器调试需要容器内需运行 debugpy 服务
Jupyter Notebook需要手动嵌入调试监听
PyCharm 调试不需要PyCharm 内置调用

debugpy 的价值主要在 远程调试无 IDE 环境;本地开发由 IDE 自动管理。

安装

pip install debugpy

命令行直接调试(无 IDE)

# 直接运行并监听
python -m debugpy --listen 5678 script.py
 
# 等待外部调试器连接(如 VS Code attach)
python -m debugpy --listen 5678 --wait-for-client script.py

任何支持 DAP 协议的工具都可以连接。

本地调试

VS Code 的 Python 扩展底层就是调用 debugpy。配置 "type": "python" 后按 F5:

用户按 F5 → VS Code Python 扩展 → 自动启动 debugpy → 调试 Python 进程

调试器与被调试程序在同一进程空间,VS Code 通过 DAP 协议与 debugpy 通信。

launch.json

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: 当前文件",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true,
            "env": {"PYTHONUNBUFFERED": "1"}
        },
        {
            "name": "Python: 模块调试",
            "type": "python",
            "request": "launch",
            "module": "my_package.main",
            "console": "integratedTerminal"
        },
        {
            "name": "Python: 带参数",
            "type": "python",
            "request": "launch",
            "program": "${workspaceFolder}/app.py",
            "args": ["--config", "dev.yaml"],
            "console": "integratedTerminal"
        }
    ]
}

关键配置

配置项说明示例
program调试目标文件${file}
module模块方式启动my_package.main
args命令行参数["--debug", "true"]
env环境变量{"DEBUG": "1"}
cwd工作目录${workspaceFolder}
console控制台类型integratedTerminal / externalTerminal
justMyCode仅调试用户代码true(跳过库代码)

调试操作

  • 断点:点行号左侧添加;右键可设条件断点(如 i > 10)、日志断点、触发断点
  • 执行控制:F5 继续 / F10 单步跳过 / F11 单步进入 / Shift+F11 跳出 / Shift+F5 停止
  • 变量监视:在”变量”面板查看;自定义表达式加到”监视”面板

远程调试

代码运行在远程服务器、Docker 容器或 SSH 环境,本地 IDE attach 到远程进程。

工作原理

┌──────────────┐                  ┌────────────────┐
│ 本地 VS Code │  ←── socket ──→  │ 远程 Python 进程│
│  (客户端)    │      5678        │  (debugpy 服务)│
└──────────────┘                  └────────────────┘

服务端(被调试方)

# 命令行启动
python -m debugpy --listen 0.0.0.0:5678 --wait-for-client app.py

或代码内嵌:

import debugpy
 
debugpy.listen(("0.0.0.0", 5678))
print("等待调试器附加...")
debugpy.wait_for_client()  # 阻塞直到 VS Code 连接
 
# 业务代码继续执行...
参数说明
--listen 0.0.0.0:5678监听所有接口,允许外部连接
--listen localhost:5678仅监听本地,需配合 SSH 隧道
--wait-for-client启动后等待调试器连接才继续执行

客户端(VS Code)

{
    "name": "Python: 远程附加",
    "type": "python",
    "request": "attach",
    "connect": {
        "host": "192.168.1.100",
        "port": 5678
    },
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/opt/project"
        }
    ]
}

路径映射

本地代码路径与远程运行路径不同,VS Code 需要映射才能正确关联断点。

场景localRootremoteRoot
项目结构相同${workspaceFolder}/app
子目录映射${workspaceFolder}/src/app/src
Windows → LinuxC:\\dev\\project/home/user/project

SSH 隧道(推荐)

直接暴露调试端口有安全风险。SSH 隧道把端口收口到本地:

ssh -L 5678:localhost:5678 user@remote-server

VS Code 改连本地:

"connect": {"host": "localhost", "port": 5678}

Docker 容器调试

docker-compose.yml

services:
  app:
    image: python:3.11
    volumes:
      - ./src:/app
    ports:
      - "5678:5678"
    command: python -m debugpy --listen 0.0.0.0:5678 --wait-for-client /app/main.py

VS Code 配置:

{
    "name": "Python: Docker 调试",
    "type": "python",
    "request": "attach",
    "connect": {"host": "localhost", "port": 5678},
    "pathMappings": [
        {"localRoot": "${workspaceFolder}/src", "remoteRoot": "/app"}
    ]
}

本地 vs 远程对比

维度本地远程
启动方式VS Code 直接启动程序独立启动,VS Code 附加
requestlaunchattach
路径映射不需要必须
适用日常开发生产复现、容器调试
启动速度较慢(需建立连接)

Jupyter Notebook

import debugpy
debugpy.listen(5678)
# VS Code 执行 "Python: 远程附加" 后,可在 Notebook 内调试

故障排除

问题原因解决
远程连接失败端口未开放 / 防火墙阻拦开放端口;确认监听 0.0.0.0
断点灰色(未命中)路径映射错误检查 pathMappings 对应关系
调试卡死死锁 / 库代码阻塞设置 justMyCode: false 看完整栈
无法进入函数justMyCode 跳过库代码设置 justMyCode: false
多进程调试失败子进程未配置"subProcess": true

最佳实践

  1. 开发:本地调试,快速迭代
  2. 环境问题排查:远程调试到真实环境
  3. Docker:端口映射 + 路径映射,保留本地编辑体验
  4. 生产:始终走 SSH 隧道,避免暴露调试端口
  5. 复杂项目:模块启动(module)优于文件启动(program

参考