使用 VS Code 远程调试 Python 程序

简介:

在上一篇文章 远程调试你的 Python 代码 中,我简单介绍了 Python 世界中的两种远程调试模型:PyCharm 选择的 debugger as debug server 模式和 VS Code 提供的 debugger as debug client 模式,并分享了 PyCharm 的远程调试适用于单体应用,VS Code 的远程调试适用于大规模的分布式应用的观点。

随后有同行来信咨询我具体如何使用 VS Code 来远程调试。由于 VS Code Python Plugin 的文档并不完善,我只好再写一篇博文来介绍如何使用 VS Code 去远程调试 Python 程序。

在阅读本文之前,我希望读者不仅要知道如何使用 VS Code 进行简单的文本编辑、目录管理,还要知道如何使用 VS Code 调试本地代码。如果不满足我的期望,阅读一些 VS Code 的文档比如 Debugging in Visual Studio Code 会很有帮助。

进入正题。

首先为了远程调试,我们需要有一段能长时间执行的 Python 代码,以及必不可少的 Python 虚拟环境。

我在开发机器上创建一套虚拟环境作为演示。

which python
python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

为了获得在 VS Code 配置 Python 开发环境需要的信息,我执行了上述两个命令,分别获取当前虚拟环境下的 Python 解释器路径和 Python 包安装路径。

用 VS Code 打开当前目录。然后在首选项中设置当前 Workspace 的配置,添加上述两个命令的输出,让 VS Code 知道用哪个 Python 解释器,去哪里寻找模块做代码索引和补全提示。


不必担心记不住配置的 Key,只要正确安装了 Python 插件(ext install python),这些配置 Key 都是有自动补全的。由于我这里没有安装 Pylint,只能把 linting 功能关闭了,不然 VS Code 会不胜其烦地提醒我安装 linter。

我们这里说的是远程调试,那么我就需要在别的机器上把我要调试的 Python 进程启动起来。正好我手上有一台闲置的 ThinkPad,前些日子被我装了 Neon 这个发行版来体验最新的 KDE,正好可以给我拿来当做 Remote Server。如果你手上没那么多闲置机器,那么用 Docker 或者虚拟机来启动个进程也是可以的,注意做好端口映射也就问题不大。

暴露写作时间系列。从上图可以看到许多关键信息,比如代码部署的位置,虚拟环境部署的位置,服务器的 IP 等等……注意到我在代码最开始的地方就设置了 ptvsd 的调试模式。

代码在远程部署好了,但是还没启动,现在让我们回到 VS Code。嗯,进入调试视图(Debug View),初始化或者打开调试配置(Launch Configurations)。如果之前没为当前的 Workspace 创建过调试配置,那么 VS Code 的 Python 插件会从模板帮我们初始化出四种不同的调试配置。但是那些都没什么用,都是为本地调试准备的(本地调试的话有必要用 VS Code 么,PyCharm 多好),都可以删掉,换成下面这段:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Remote",
            "type": "python",
            "request": "attach",
            "host": "192.168.2.113",
            "port": 8000,
            "localRoot": "${workspaceRoot}",
            "remoteRoot": "/tmp/py-remote-debug-example"
        }
    ]
}

这里面有几个需要根据实际情况修改的参数,比如 host 要写目标进程所在的主机,port 要写目标进程里面初始化 ptvsd 时监听的调试端口,remoteRoot 要写远程主机上代码部署的位置的绝对路径,这样 VS Code 才能把本地代码文件和远程代码文件匹配起来。

由于 VS Code Python Plugin 的文档中没有明确给出远程调试的配置方式,我也是翻了它的代码才最终确定的,虽然在翻代码之前就在自动补全的帮助下瞎蒙出来了。

VS Code 的配置到这里就基本上告一段落了。接下来就是在服务器上启动进程,然后在 VS Code 里启动调试,然后装模作样地下断点,在断点附近对表达式求值……

So far so good. 那么问题来了,如果我不仅仅要调试项目中的代码,我还要调试安装到虚拟环境中的第三方库,能做到吗?比如我要单步进入 requests.get 方法。于是我进入 get 方法,下了断点,然后点下绿色的三角按钮,等待奇迹发生。

然而奇迹并没有发生。

VS Code 说它找不到代码。Source /private/home/panjiabang/.virtualenvs/remote-debug/lib/python2.7/site-packages/requests/api.py is not available.

虽然不知道为啥 VS Code 会去 /private 这个 OS X 不知道跟谁学来的目录里找东西,但是我的直觉告诉我,这一定是远程机器上的第三方库的绝对路径和本地机器路径不一致造成的。ptvsd 作为调试服务器,肯定不知道客户端的三方库在哪也不需要知道,老老实实把服务器上三方库的路径给到 debugger,结果 VS Code Python 插件里的 debugger 也傻傻的不知道做个转换,直接就拿远程的路径到本地去找代码,找得到才怪了。

这明显是 VS Code Python 插件的设计缺陷啊,好歹提供一个配置,做个 site-package 目录的映射什么的,而且不能是 1:1 的映射,得是 m:n 的映射,因为 Python 找模块时用的 sys.path 还是有不少的。不过考虑到我们在部署的时候,实际上会把所有的依赖都打包在虚拟环境的 site-package 目录下,所以大多数场景下,只要映射远程的 site-package 和本地的 site-package 就妥妥的够用了。在没有官方的解决方案之前,我只好将就一下,在本地做个软链,让 VS Code 能用远程的路径在本地找到代码。

可算是断点到 requests 里头了,真不容易

不得不说,作为一个图形化调试器,VS Code 做得还是很不错,基本上现代调试器该有的功能都有了,比如鼠标悬停在变量上方就显示变量的值,选中变量后右键功能支持求值、观察等等,比起 PyCharm 之流不遑多让。但是作为一个 IDE 还是太弱了,虽然支持 linting,但是检查出来的 warning 不支持自动修复,局部变量重命名居然会漏掉几处,无法分析类间关系、函数覆盖……

因为 VS Code 支持 Python 远程调试的缘故,我近期越来越多地使用它,也渐渐发现一些痛点,这些痛点让我一直无法完全信赖 VS Code。最大的痛点就是文本替换的时候不支持多行正则(https://github.com/Microsoft/vscode/issues/313,今天很高兴发现这个 issue 已经有相关的 commit 了,估计会在 7 月的新版本中支持,到时候我就能完全抛弃 Sublime Text 了吧)。

如果我还有闲暇时间,或许会尝试给 VS Code Python Plugin 加上 site-package 目录映射什么的。不过我更想要做的,是给 PyCharm 写一个 Remote Debug 的插件,配合 ptvsd 实现远程调试,毕竟 PyCharm 是更加靠谱的 Python IDE。文本编辑器嘛,用来写写博客,敲点简单的代码片段就挺好,复杂的项目还是交给更专业的程序去帮我节约时间。

目录
相关文章
|
7天前
|
数据处理 UED Python
Python 进度条:告别枯燥等待,让你的程序动感十足!
Python 进度条:告别枯燥等待,让你的程序动感十足!
27 1
|
1天前
|
Shell 数据处理 C++
【震撼揭秘】Python正则VS Shell正则:一场跨越编程边界的史诗级对决!你绝不能错过的精彩较量,带你领略文本处理的极致魅力!
【8月更文挑战第19天】正则表达式是文本处理的强大工具,在Python与Shell中有广泛应用。两者虽语法各异,但仍共享许多基本元素,如`.`、`*`及`[]`等。Python通过`re`模块支持丰富的功能,如非捕获组及命名捕获组;而Shell则依赖`grep`、`sed`和`awk`等命令实现类似效果。尽管Python提供了更高级的特性和函数,Shell在处理文本文件方面仍有其独特优势。选择合适工具需根据具体需求和个人偏好决定。
|
19天前
|
TensorFlow 算法框架/工具 Python
【Mac 系统】解决VSCode用Conda成功安装TensorFlow但程序报错显示红色波浪线Unable to import ‘tensorflow‘ pylint(import-error)
本文解决在Mac系统上使用VSCode时遇到的TensorFlow无法导入问题,原因是Python解析器未正确设置为Conda环境下的版本。通过在VSCode左下角选择正确的Python解析器,即可解决import TensorFlow时报错和显示红色波浪线的问题。
30 9
|
17天前
|
Linux 开发工具 Python
【Deepin 20系统】Linux系统从零打造完美VScode for Python环境
如何在Deepin 20系统中从零开始配置一个完美的VScode for Python开发环境,包括安装Anaconda、VScode、必要的插件、汉化、主题和字体设置,以及如何运行和调试Python程序。
29 5
|
14天前
|
机器学习/深度学习 数据可视化 数据处理
Python vs R:机器学习项目中的实用性与生态系统比较
【8月更文第6天】Python 和 R 是数据科学和机器学习领域中最受欢迎的两种编程语言。两者都有各自的优点和适用场景,选择哪种语言取决于项目的具体需求、团队的技能水平以及个人偏好。本文将从实用性和生态系统两个方面进行比较,并提供代码示例来展示这两种语言在典型机器学习任务中的应用。
38 1
|
21天前
|
IDE Linux 开发工具
Python中编写第一个 Python 程序
【7月更文挑战第27天】
21 7
|
17天前
|
消息中间件 网络协议 Python
信号传递新风尚!Python IPC,让你的程序间沟通无界限
【8月更文挑战第3天】在多程序系统中,进程间通信(IPC)是实现数据共享与协作的关键。Python提供多种IPC机制,如管道、消息队列和套接字,使信息交流高效灵活。通过`multiprocessing.Pipe()`,进程间可直接传递消息;利用消息队列实现异步通信,提高解耦与扩展性;借助socket库,支持网络内外进程通信。合理运用这些技术,能够显著增强程序间的协同能力,构建更灵活、可扩展的系统。
34 1
|
18天前
|
机器学习/深度学习 数据可视化 算法
决策树VS世界:掌握Python机器学习中的这棵树,决策从此不再迷茫
【8月更文挑战第2天】在数据驱动时代,决策树作为一种直观且易于解释的机器学习方法,因其强大的分类与回归能力备受青睐。本文介绍决策树的基础概念:通过属性测试划分数据,优化选择以提高预测准确度。使用Python的scikit-learn库,我们演示了如何加载鸢尾花数据集,构建并训练决策树模型,评估其准确性,以及利用`plot_tree`函数可视化决策过程,从而更好地理解模型的工作原理。掌握这些技能,你将在面对复杂决策时更加自信。
17 2
|
19天前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【8月更文挑战第1天】在编程世界中,进程间通信(IPC)犹如一场社交舞会,各进程通过IPC机制优雅地交换信息,共同完成复杂任务。IPC就像隐形桥梁,连接并行运行的进程,使它们能跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存和套接字等,适应不同需求。例如,使用`multiprocessing.Queue`实现进程间通信,生产者向队列添加数据,消费者取出并处理数据,两者虽独立却能有效协作。IPC打破了进程界限,使得程序能像社交达人般自由交流,构建出高效、灵活的应用。掌握IPC,让程序信息畅通无阻。
16 1
|
21天前
|
JSON 监控 开发者
Python I/O管理新篇章:优化你的程序,让数据流动更顺畅
【7月更文挑战第30天】在数据驱动时代, Python I/O操作效率至关重要。理解I/O瓶颈,使用缓冲技术(如调整`open`的`buffering`参数),并发与异步I/O(借助`asyncio`),高效序列化(json, msgpack),及监控调试(cProfile)能显著提升性能。示例展示了缓冲读取和异步文件操作的最佳实践。不断学习可助开发者优化数据流。
37 2