使⽤VSCode远程调试Python程序python虚拟机
在上⼀篇⽂章 中,我简单介绍了 Python 世界中的两种远程调试模型:PyCharm 选择的 debugger as debug server 模式和 VS Code 提供的 debugger as debug client 模式,并分享了 PyCharm 的远程调试适⽤于单体应⽤,VS Code 的远程调试适⽤于⼤规模的分布式应⽤的观点。
随后有同⾏来信咨询我具体如何使⽤ VS Code 来远程调试。由于 的⽂档并不完善,我只好再写⼀篇博⽂来介绍如何使⽤ VS Code 去远程调试 Python 程序。
在阅读本⽂之前,我希望读者不仅要知道如何使⽤ VS Code 进⾏简单的⽂本编辑、⽬录管理,还要知道如何使⽤ VS Code 调试本地代码。如果不满⾜我的期望,阅读⼀些 VS 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. 那么问题来了,如果我不仅仅要调试项⽬中的代码,我还要调试安装到虚拟环境中的第三⽅库,能做到吗?⽐如我要单步进⼊ ⽅法。于是我进⼊ 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 Plugin 加上 site-package ⽬录映射什么的。不过我更想要做的,是给 PyCharm 写⼀个 Remote Debug 的插件,配合 ptvsd 实现远程调试,毕竟 PyCharm 是更加靠谱的 Python IDE。⽂本编辑器嘛,⽤来写写博客,敲点简单的代码⽚段就挺好,复杂的项⽬还是交给更专业的程序去帮我节约时间。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。