当前位置: 首页 > news >正文

让 VSCode 调试器像 PyCharm 一样显示 Tensor Shape、变量形状、变量长度、维度信息

文章目录

    • 🎯 目标:在 VS Code 调试器中自动显示这些变量信息
    • 🔍 原理简介
      • ⚠️ 其他方案的局限性
        • ❌ 方案一:重写 `__repr__`
        • ❌ 方案二:向 debugpy 注册自定义变量显示器(StrPresentationProvider)
    • ✅ 我的方案优势
    • 🛠️ 具体实现步骤
      • 1. 找到 debugpy 对应的文件目录
        • 对于 Windows 用户
        • 对于 Ubuntu / Linux 用户
      • 2. 修改 `get_variable_details()` 函数
    • 📊 工作流程解析
    • ⚠️ 注意事项
    • 📚 参考文献


你是否也有这样的痛点:在 PyCharm 中调试深度学习模型或代码时,变量区会清晰显示每个变量的 shape 和类型信息,而在 VS Code 中却只能看到一团 tensor(...)?别急,这篇文章带你一步一步打造 VS Code 的“PyCharm 式调试体验”。

先看 VS Code 调试效果图

在这里插入图片描述

🎯 目标:在 VS Code 调试器中自动显示这些变量信息

  • torch.Tensor: 显示 {Tensor: (3, 4)}
  • numpy.ndarray: 显示 {ndarray: (2, 2)}
  • pandas.DataFrame: 显示 {DataFrame: (5, 3)}
  • listdictsettuple: 显示长度 {list: 3}{dict: 3}{set: 3}{tuple: 3}

🔍 原理简介

VS Code 的 Python 调试器底层使用的是 debugpy,其中,变量的显示格式由 pydevd_xml.py 中的 get_variable_details() 函数控制。通过修改该函数逻辑,我们可以为常见的数据结构注入形状(shape)或长度(len)信息,使其直接显示在调试面板中。

⚠️ 其他方案的局限性

在社区中也存在一些尝试解决此问题的方案,但大多存在以下缺陷:

❌ 方案一:重写 __repr__

一种直观的做法是通过自定义 __repr__ 方法来改变变量在调试器中的显示方式【在 VS Code 中调试 Tensor 形状不显示的问题及解决方案】。这种方式可以实现变量显示的定制化,但它 无法影响调试器中内置类型(如 boolintstr 等)的显示行为

❌ 方案二:向 debugpy 注册自定义变量显示器(StrPresentationProvider)

另一种方法是利用 debugpy 提供的扩展机制,注册一个 StrPresentationProvider,告诉调试器如何渲染特定类型的变量。【在 VS Code 调试器中自动显示变量形状和维度信息】【VS Code 中为调试器增强变量显示:自动显示张量 Shape、DataFrame 维度和容器长度】。这种方法虽然理论上更优雅,但在实际使用中发现,它会 读取原始的完整变量内容 来生成字符串表示,这在面对大型数组、DataFrame 或嵌套结构时会导致 严重卡顿甚至崩溃,严重影响调试体验。

✅ 我的方案优势

我选择从 debugpy 内部机制入手,通过修改其源码中的 get_variable_details() 函数,在变量渲染阶段注入形状信息,从而避免了上述方法的性能问题和副作用。

这一改动仅作用于调试器前端显示层,不会影响程序运行逻辑,也不会因变量过大而造成性能瓶颈。

而且,debugpy 在内部已经对变量内容做了优化处理,只读取必要的元数据(如 shape、dtype、len)而不加载整个对象内容,因此能保持几乎与原始 VS Code 调试器相同的响应速度。


🛠️ 具体实现步骤

1. 找到 debugpy 对应的文件目录

根据你使用的编辑器和操作系统,找到对应的文件目录:

对于 Windows 用户

如果你使用的是 VS Code 或基于 VS Code 内核的编辑器(例如 Cursor),则路径通常如下:

  • VS Code:
C:\Users\Tang\.vscode\extensions\ms-python.debugpy-2025.10.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_xml.py
  • Cursor:
C:\Users\Tang\.cursor\extensions\ms-python.debugpy-2025.8.0-win32-x64\bundled\libs\debugpy\_vendored\pydevd\_pydevd_bundle\pydevd_xml.py

💡 注意:实际路径可能会有所不同,请根据实际情况调整。

对于 Ubuntu / Linux 用户

如果你使用的是 Ubuntu 或其他 Linux 发行版,路径通常如下:

  • VS Code:
~/.vscode-server/extensions/ms-python.debugpy-2025.10.0-linux-x64/bundled/libs/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_xml.py
  • Cursor:
~/.cursor-server/extensions/ms-python.debugpy-2025.6.0-linux-x64/bundled/libs/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_xml.py

💡 注意:我写的是远程 remote-ssh 的服务器路径,本地路径可能会有所不同比如.cursor-server换成.cursor等,请根据实际情况调整。


2. 修改 get_variable_details() 函数

修改之前做好备份

打开 pydevd_xml.py 文件,找到get_variable_details()函数,完整修改之后如下:

def get_variable_details(val, evaluate_full_value=True, to_string=None, context: Optional[str] = None):""":param context:This is the context in which the variable is being requested. Valid values:"watch","repl","hover","clipboard""""try:# This should be faster than isinstance (but we have to protect against not having a '__class__' attribute).is_exception_on_eval = val.__class__ == ExceptionOnEvaluateexcept:is_exception_on_eval = Falseif is_exception_on_eval:v = val.resultelse:v = val_type, type_name, resolver = get_type(v)type_qualifier = getattr(_type, "__module__", "")if not evaluate_full_value:value = DEFAULT_VALUEelse:try:# 添加形状信息shape_info = ""try:# 处理 PyTorch Tensorif type_qualifier == "torch" and hasattr_checked(v, 'shape') and hasattr_checked(v, 'dtype'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{Tensor: {shape}}} "# 处理 NumPy ndarrayelif type_qualifier == "numpy" and hasattr_checked(v, 'shape') and hasattr_checked(v, 'dtype'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{ndarray: {shape}}} "# 处理 Pandas DataFrameelif type_qualifier == "pandas.core.frame" and hasattr_checked(v, 'shape'):shape = tuple(v.shape)shape_info = f"{{DataFrame: {shape}}} "# 处理 Pandas Serieselif type_qualifier == "pandas.core.series" and hasattr_checked(v, 'shape'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{Series: {shape}}} "# 处理其他有 shape 属性的对象elif hasattr_checked(v, 'shape'):shape_info = f"{{{v.shape}}} "# 处理可计数对象elif hasattr_checked(v, '__len__'):try:length = len(v)shape_info = f"{{{type_name}: {length}}} "except:passexcept:passstr_from_provider = _str_from_providers(v, _type, type_name, context)if str_from_provider is not None:value = shape_info + str_from_providerelif to_string is not None:value = shape_info + to_string(v)elif hasattr_checked(v, "__class__"):if v.__class__ == frame_type:value = pydevd_resolver.frameResolver.get_frame_name(v)elif v.__class__ in (list, tuple):if len(v) > 300:value = "%s: %s" % (str(v.__class__), "<Too big to print. Len: %s>" % (len(v),))else:value = "%s: %s" % (str(v.__class__), v)else:try:cName = str(v.__class__)if cName.find(".") != -1:cName = cName.split(".")[-1]elif cName.find("'") != -1:  # does not have '.' (could be something like <type 'int'>)cName = cName[cName.index("'") + 1 :]if cName.endswith("'>"):cName = cName[:-2]except:cName = str(v.__class__)value = "%s: %s" % (cName, v)else:value = shape_info + str(v)except:try:value = repr(v)except:value = "Unable to get repr for %s" % v.__class__# fix to work with unicode valuestry:if value.__class__ == bytes:value = value.decode("utf-8", "replace")except TypeError:passreturn type_name, type_qualifier, is_exception_on_eval, resolver, value

具体来说,在 get_variable_details() 函数中添加了1处内容,并修改了3处内容,具体如下:

  1. 添加了1处内容。
    找到if not evaluate_full_value:这个地方,进行下面的添加:
if not evaluate_full_value:value = DEFAULT_VALUE
else:try:# 添加形状信息shape_info = ""try:# 处理 PyTorch Tensorif type_qualifier == "torch" and hasattr_checked(v, 'shape') and hasattr_checked(v, 'dtype'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{Tensor: {shape}}} "# 处理 NumPy ndarrayelif type_qualifier == "numpy" and hasattr_checked(v, 'shape') and hasattr_checked(v, 'dtype'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{ndarray: {shape}}} "# 处理 Pandas DataFrameelif type_qualifier == "pandas.core.frame" and hasattr_checked(v, 'shape'):shape = tuple(v.shape)shape_info = f"{{DataFrame: {shape}}} "# 处理 Pandas Serieselif type_qualifier == "pandas.core.series" and hasattr_checked(v, 'shape'):shape = tuple(v.shape)dtype = str(v.dtype)shape_info = f"{{Series: {shape}}} "# 处理其他有 shape 属性的对象elif hasattr_checked(v, 'shape'):shape_info = f"{{{v.shape}}} "# 处理可计数对象elif hasattr_checked(v, '__len__'):try:length = len(v)shape_info = f"{{{type_name}: {length}}} "except:passexcept:pass
  1. 然后在构建最终显示值时,将 shape_info 插入前面,共3处:

value = str_from_provider修改如下:

value = shape_info + str_from_provider

value = to_string(v)修改如下:

value = shape_info + to_string(v)

value = str(v)修改如下:

value = shape_info + str(v)

📊 工作流程解析

当我们在 VS Code 中启动调试会话时,整个流程如下:

  1. VS Code 启动调试器并加载内置的 debugpy 模块。
  2. debugpy 连接到目标 Python 程序并开始监听断点。
  3. 当程序暂停时,debugpy 收集当前作用域内的变量信息。
  4. 在变量渲染阶段,调用 get_variable_details() 函数生成显示字符串。
  5. 我们的修改在此处注入形状信息。
  6. 最终结果返回给 VS Code 前端展示。

需要注意的是,VS Code 优先使用其自带的 debugpy,而不是环境中的 pip 安装版本。因此,我们的修改需针对 VS Code 扩展目录中的源文件。


⚠️ 注意事项

  1. VS Code 更新覆盖修改:每次更新 VS Code 或 Python 扩展后,可能需要重新应用修改。
  2. 备份原始文件:修改前务必备份原文件,以便恢复或对比。

📚 参考文献

  1. 在 VS Code 中调试 Tensor 形状不显示的问题及解决方案
  2. VS Code 中为调试器增强变量显示:自动显示张量 Shape、DataFrame 维度和容器长度
  3. 在 VS Code 调试器中自动显示变量形状和维度信息
http://www.dtcms.com/a/275452.html

相关文章:

  • 「日拱一码」025 机器学习——评价指标
  • Android音视频探索之旅 | C++层使用OpenGL ES实现音频渲染
  • 单片机学习笔记.根据芯片数据手册写驱动程序(这里使用的是普中开发版,以DS1302为例)
  • 创建Spring Boot项目
  • 解决‘vue‘ 不是内部或外部命令,也不是可运行的程序
  • 前端开发的「设计鸿沟」:为什么我学了CSS却做不出好看的网页?
  • 用YOLOv5系列教程(1)-用YOLOv5轻松实现设备状态智能监控!工业级教程来了
  • 【工具】什么软件识别重复数字?
  • C++结构体的定义与使用
  • 机器学习(ML)、深度学习(DL)、强化学习(RL)关系和区别
  • Redis 基本操作笔记
  • 关于wpf的自适应
  • 基于 Redisson 实现分布式系统下的接口限流
  • [特殊字符] 深入掌握 dsquery:Active Directory 高效查询与安全运维指南
  • sqli-labs靶场通关笔记:第7-8关 布尔盲注
  • Gemini CLI 代理问题解决[API Error: exception TypeError: fetch failed sending request]
  • 【Linux-云原生-笔记】数据库操作基础
  • 【机器学习|学习笔记】详解决策树CART算法,并对比ID3 C4.5和CART算法
  • 系统分析师-计算机系统-计算机系统概述存储系统
  • 内网穿透系列九:开源的网络穿透与组网工具 EasyTier,支持多种数据传输通道,去中心化,兼具高效与安全
  • 【Java八股文总结 — 包学会】(二)计算机网络
  • PyTorch的计算图是什么?为什么绘图前要detach?
  • 【设计模式】单例模式 饿汉式单例与懒汉式单例
  • 人工智能自动化编程:传统软件开发vs AI驱动开发对比分析
  • 云原生技术与应用-生产环境构建高可用Harbor私有镜像仓库
  • ​BRPC核心架构解析:高并发RPC框架的设计哲学
  • Whistle抓包
  • 【设计模式】桥接模式(柄体模式,接口模式)
  • 为什么有些PDF无法复制文字?原理分析与解决方案
  • Oxygen XML Editor 26.0编辑器