天天看點

使用 VS Code 遠端調試 Python 程式

進入正題。

首先為了遠端調試,我們需要有一段能長時間執行的 python 代碼,以及必不可少的 python 虛拟環境。

我在開發機器上建立一套虛拟環境作為示範。

使用 VS Code 遠端調試 Python 程式

為了獲得在 vs code 配置 python 開發環境需要的資訊,我執行了上述兩個指令,分别擷取目前虛拟環境下的 python 解釋器路徑和 python 包安裝路徑。

用 vs code 打開目前目錄。然後在首選項中設定目前 workspace 的配置,添加上述兩個指令的輸出,讓 vs code 知道用哪個 python 解釋器,去哪裡尋找子產品做代碼索引和補全提示。

使用 VS Code 遠端調試 Python 程式
使用 VS Code 遠端調試 Python 程式

不必擔心記不住配置的 key,隻要正确安裝了 python 插件(ext install python),這些配置 key 都是有自動補全的。由于我這裡沒有安裝 <code>pylint</code>,隻能把 linting 功能關閉了,不然 vs code 會不勝其煩地提醒我安裝 linter。

我們這裡說的是遠端調試,那麼我就需要在别的機器上把我要調試的 python 程序啟動起來。正好我手上有一台閑置的 thinkpad,前些日子被我裝了 neon 這個發行版來體驗最新的 kde,正好可以給我拿來當做 remote server。如果你手上沒那麼多閑置機器,那麼用 docker 或者虛拟機來啟動個程序也是可以的,注意做好端口映射也就問題不大。

使用 VS Code 遠端調試 Python 程式

暴露寫作時間系列。從上圖可以看到許多關鍵資訊,比如代碼部署的位置,虛拟環境部署的位置,伺服器的 ip 等等……注意到我在代碼最開始的地方就設定了 ptvsd 的調試模式。

代碼在遠端部署好了,但是還沒啟動,現在讓我們回到 vs code。嗯,進入調試視圖(debug view),初始化或者打開調試配置(launch configurations)。如果之前沒為目前的 workspace 建立過調試配置,那麼 vs code 的 python 插件會從模闆幫我們初始化出四種不同的調試配置。但是那些都沒什麼用,都是為本地調試準備的(本地調試的話有必要用 vs code 麼,pycharm 多好),都可以删掉,換成下面這段:

這裡面有幾個需要根據實際情況修改的參數,比如 <code>host</code> 要寫目标程序所在的主機,<code>port</code> 要寫目标程序裡面初始化 <code>ptvsd</code> 時監聽的調試端口,<code>remoteroot</code> 要寫遠端主機上代碼部署的位置的絕對路徑,這樣 vs code 才能把本地代碼檔案和遠端代碼檔案比對起來。

vs code 的配置到這裡就基本上告一段落了。接下來就是在伺服器上啟動程序,然後在 vs code 裡啟動調試,然後裝模作樣地下斷點,在斷點附近對表達式求值……

使用 VS Code 遠端調試 Python 程式

so far so good. 那麼問題來了,如果我不僅僅要調試項目中的代碼,我還要調試安裝到虛拟環境中的第三方庫,能做到嗎?比如我要單步進入 <code>requests.get</code> 方法。于是我進入 get 方法,下了斷點,然後點下綠色的三角按鈕,等待奇迹發生。

然而奇迹并沒有發生。

使用 VS Code 遠端調試 Python 程式

vs code 說它找不到代碼。source /private/home/panjiabang/.virtualenvs/remote-debug/lib/python2.7/site-packages/requests/api.py is not available.

雖然不知道為啥 vs code 會去 <code>/private</code> 這個 os x 不知道跟誰學來的目錄裡找東西,但是我的直覺告訴我,這一定是遠端機器上的第三方庫的絕對路徑和本地機器路徑不一緻造成的。ptvsd 作為調試伺服器,肯定不知道用戶端的三方庫在哪也不需要知道,老老實實把伺服器上三方庫的路徑給到 debugger,結果 vs code python 插件裡的 debugger 也傻傻的不知道做個轉換,直接就拿遠端的路徑到本地去找代碼,找得到才怪了。

這明顯是 vs code python 插件的設計缺陷啊,好歹提供一個配置,做個 <code>site-package</code> 目錄的映射什麼的,而且不能是 1:1 的映射,得是 m:n 的映射,因為 python 找子產品時用的 <code>sys.path</code> 還是有不少的。不過考慮到我們在部署的時候,實際上會把所有的依賴都打包在虛拟環境的 <code>site-package</code> 目錄下,是以大多數場景下,隻要映射遠端的 <code>site-package</code> 和本地的 <code>site-package</code> 就妥妥的夠用了。在沒有官方的解決方案之前,我隻好将就一下,在本地做個軟鍊,讓 vs code 能用遠端的路徑在本地找到代碼。

使用 VS Code 遠端調試 Python 程式

可算是斷點到 requests 裡頭了,真不容易

不得不說,作為一個圖形化調試器,vs code 做得還是很不錯,基本上現代調試器該有的功能都有了,比如滑鼠懸停在變量上方就顯示變量的值,選中變量後右鍵功能支援求值、觀察等等,比起 pycharm 之流不遑多讓。但是作為一個 ide 還是太弱了,雖然支援 linting,但是檢查出來的 warning 不支援自動修複,局部變量重命名居然會漏掉幾處,無法分析類間關系、函數覆寫……

如果我還有閑暇時間,或許會嘗試給 vs code python plugin 加上 <code>site-package</code> 目錄映射什麼的。不過我更想要做的,是給 pycharm 寫一個 remote debug 的插件,配合 ptvsd 實作遠端調試,畢竟 pycharm 是更加靠譜的 python ide。文本編輯器嘛,用來寫寫部落格,敲點簡單的代碼片段就挺好,複雜的項目還是交給更專業的程式去幫我節約時間。