目錄
- 摘要
- 調試工具窗口
- 會話
- 工具欄
- 調試工具欄
- 單步工具欄
- 調試器選項卡
- 調用棧幀(Frames)
- 變量(Variables)
- 💡 表達式求值區域(Evaluate expression field)
- 🖱? 右鍵菜單(Context Menu)
- 變量類型
- 監視(Watches)
- 表達式求值字段(Evaluate expression field)
- 工具欄(Toolbar)
- 右鍵菜單(Context menu)
- 調試過程
- 斷點
- 斷點類型
- 設置斷點
- 管理斷點
- 斷點圖標
- 啟動調試器會話
- 檢查掛起的程序
- 逐步執行程序
- 使用 PyCharm 進行遠程調試
- 使用調試控制臺
- 尾聲
摘要
寫代碼這么多年,我一直是“打印派”的忠實擁躉。每當程序出了問題,我下意識地就在關鍵位置加上 print()
或 pprint()
來輸出變量、狀態或者程序流程。對于一些小項目,這種方式確實簡單高效,也容易快速定位問題。
但當我開始開發更加復雜的應用,比如 AI Agent 系統,print 調試就顯得力不從心了。大量的模塊調用、異步邏輯、狀態切換,讓單純靠打印信息已經難以理清整個程序的運行脈絡。而一不小心,滿屏的調試信息不僅沒幫我找到問題,反而制造了更多干擾。
這時候,我開始認真學習 PyCharm 的調試工具。從最基本的斷點設置,到條件斷點、變量追蹤、堆棧查看,再到 Evaluate Expression、數據修改和多線程調試等進階功能,PyCharm 提供了一整套強大的調試能力,幾乎能覆蓋所有開發場景。
本篇博客將系統講解我從“print 調試”逐步轉向“IDE 調試”的心路歷程,并結合一些真實的項目案例,介紹如何使用 PyCharm 的 Debug 功能來高效排查和解決復雜問題。無論你是初學者,還是像我一樣長年“只用打印”的開發者,都可以從中找到屬于你的調試利器。
調試工具窗口
當你啟動調試會話時,Debug 工具窗口會自動打開。你可以使用這個窗口來控制調試過程,查看和分析程序數據(如調用棧、變量等),并執行各種調試操作。
默認情況下,當程序運行到斷點時,Debug 工具窗口會自動打開,并且在調試會話結束后不會自動關閉。
如果你想修改這個行為,可以前往 Build, Execution, Deployment | Debugger 設置頁面(快捷鍵 Ctrl+Alt+S
),取消勾選 Show debug window on breakpoint(在斷點處顯示調試窗口) 選項即可。
-
- Sessions tabs:會話選項卡
-
- Debugger console tab:調試器控制臺選項卡
-
- Variables and watches:變量與監視
-
- Frames:調用棧幀
-
- Debugger toolbar:調試工具欄
會話
可用的調試會話被分隔在 調試 工具窗口頂部的選項卡中。
如果您為特定的運行/調試配置 啟用了服務工具窗口 ,那么當您調試這些配置時,調試工具窗口的整個視圖將顯示在服務工具窗口中。
編輯器中的所有信息,例如 內聯變量值和執行點,都會顯示在選定的會話選項卡中。 如果您同時運行多個使用相同的調試會話,這一點很重要。
當您關閉一個選項卡時,相應的調試會話會終止。
工具欄
調試器工具欄包含 控制調試器會話和 單步操作的最常用操作。
您可以根據自己的喜好配置工具欄上可用的操作列表。
-
要添加調試操作,請右鍵單擊調試器工具欄,從上下文菜單中選擇 添加到調試器工具欄 ,然后從列表中選擇所需的操作。
-
要添加與調試無直接關系的操作,請右鍵單擊調試器工具欄,然后從上下文菜單中選擇 自定義工具欄。
在打開的對話框中,單擊 添加 ,然后選擇所需的操作。
調試工具欄
無論選擇了哪個選項卡,您始終可以在窗口左側使用以下工具欄控件,以傳統UI為例:
項目 | 工具提示和快捷鍵 | 描述 |
---|---|---|
重新運行 CtrlF5 | 點擊此按鈕以停止當前應用程序并再次運行(繼續運行直到下一個斷點)。 | |
恢復程序 F9 | 當應用程序暫停時,點擊此按鈕以恢復程序執行。 | |
暫停程序 Ctrl+Pause | 點擊此按鈕以暫停程序執行。 | |
停止 CtrlF2 | 單擊此按鈕通過標準 | |
查看斷點 CtrlShiftF8 | 點擊此按鈕以打開 斷點 對話框,您可以在其中配置斷點行為。 | |
靜音斷點 | 使用此按鈕切換斷點狀態。 當 您可以暫時靜音項目中的所有斷點,以便在不中斷斷點的情況下執行程序。 | |
設置 | 點擊此按鈕以打開包含以下選項的菜單:
| |
固定選項卡頁 | 點擊此按鈕以固定或取消固定當前選項卡。 當窗口中的標簽頁達到最大數量時,您可能需要將一個標簽頁固定,防止其自動關閉。 |
單步工具欄
項目 | 工具提示和快捷鍵 | 描述 |
---|---|---|
顯示執行點 AltF10 | 點擊此按鈕以突出顯示編輯器中的當前執行點,并在 窗口 窗格中顯示相應的堆棧幀。 | |
步過 F8 | 點擊此按鈕以執行程序,直到當前方法或文件中的下一行,跳過當前執行點引用的方法(如果有)。 如果當前行是方法中的最后一行,執行步驟將跳轉到該方法之后執行的行。 | |
步入 F7 | 點擊此按鈕以使調試器進入當前執行點調用的方法。 | |
強制步入 AltShiftF7 | 點擊此按鈕以使調試器進入當前執行點中調用的方法,即使該方法將被跳過。 | |
單步執行我的代碼 AltShiftF7 | 點擊此按鈕以跳過進入庫源代碼,并專注于您的代碼。 | |
步出 ShiftF8 | 點擊此按鈕可使調試器退出當前方法,并跳至其后執行的行。 | |
運行到光標處 AltF9 | 點擊此按鈕以恢復程序執行,并暫停直到執行點到達編輯器中當前光標位置的行。 不需要斷點。 實際上,在光標處為當前行設置了一個臨時斷點,一旦程序執行暫停,該斷點就會被移除。 因此,如果文本光標位于已執行的行,程序將只是恢復執行,因為無法回滾到先前的斷點。 此操作在您深入方法序列且需要一次退出多個方法時特別有用。 如果在應該執行的行上設置了斷點,在到達指定行之前,調試器會在遇到的第一個斷點處暫停。 tip:當您需要在特定行設置一種臨時斷點,而程序執行不應中斷時,請使用此操作。 | |
評估表達式 AltF8 | 點擊此按鈕可 評估表達式。 |
調試器選項卡
調用棧幀(Frames)
Threads & Variables 選項卡中的 Frames 面板(調用棧幀)可用于查看當前應用程序中的所有線程列表。
要檢查某個線程,只需從面板頂部的線程列表中選擇它。每個線程的狀態和類型會通過圖標和線程名稱旁的文字說明進行標識。
對于選中的線程,你可以:
- 查看其調用棧幀(Stack Frame)
- 展開并檢查各級幀(函數調用)
- 在幀之間導航
- 自動跳轉到該幀對應的源代碼位置
如需查看某個調用幀中保存的變量值,請使用 Debug 工具窗口中的 Variables(變量) 面板。
線程圖標(每個線程旁的圖標表示該線程的狀態):
變量(Variables)
Threads & Variables 選項卡中的 Variables 面板 可用于查看應用程序中各個對象的實際值。
當你在 Frames 面板 中選中了某個調用棧幀后,Variables 面板 會顯示該幀作用域內的所有數據,包括方法參數、本地變量和實例變量等。
在這個面板中,你可以執行以下操作:
- 為對象設置標簽
- 展開并查看對象的內部結構
- 評估任意表達式
- 將變量添加到監視列表(Watches)
- 以及更多調試相關操作
💡 表達式求值區域(Evaluate expression field)
當 Watches 面板 處于隱藏狀態時,Variables 面板 中會顯示一個 “表達式求值” 輸入框,用于直接輸入并計算任意表達式。
- 要評估某個表達式,只需在此字段中輸入表達式,然后按
Enter
鍵即可。 - 結果將直接顯示在下方。你還可以點擊輸入框右側的圖標,將該表達式添加到監視列表中,便于后續持續追蹤。
🖱? 右鍵菜單(Context Menu)
項目 | 快捷鍵 | 說明 |
---|---|---|
新建監視(New Watch) | – | 創建一個新的監視表達式。會打開一個文本輸入框,你可以在其中輸入要監視的表達式。 |
刪除監視(Remove Watch) | Delete | 刪除當前選中的監視表達式。 |
編輯(Edit) | F2 | 修改當前選中的監視表達式。 |
刪除所有監視(Remove All Watches) | – | 一次性刪除所有監視表達式。 |
自定義數據視圖(Customize Data View) | – | 添加自定義類型渲染器(type renderer),用于以特定方式展示某些對象。 |
檢查(Inspect) | – | 適用于字段、局部變量和引用表達式。打開一個非模態的“檢查”窗口,便于集中查看某個對象引用。你可以同時打開多個檢查窗口,它們的視圖與監視面板一致,但更節省空間。 |
設置值(Set Value) | F2 | 修改某個字段或變量在運行時的值。 |
復制值(Copy Value) | Ctrl+C | 將選中變量的值復制到剪貼板。如果選中多個變量,不僅值會被復制,結構也會保留,粘貼到文本文件時格式會自動縮進,類似調試器的樹形結構,方便閱讀。你也可以將鼠標懸停在值上查看其內容。 |
復制 JSON(Copy JSON) | – | 僅在 JavaScript 上下文中可用。以 JSON 格式復制選中的值。 |
與剪貼板中的值比較(Compare Value with Clipboard) | – | 將當前選中變量的值與剪貼板中的內容進行比較。 |
復制名稱(Copy Name) | – | 復制當前選中變量的名稱到剪貼板。 |
評估表達式(Evaluate Expression) | Alt+F8 | 在彈出的對話框中對選中的變量進行表達式求值。 |
添加到監視(Add to Watches) | – | 為當前選中的節點(非靜態節點)創建表達式并添加到監視面板中。 |
顯示引用此對象的實例(Show Referring Objects) | – | 查看哪些對象引用了當前選中的變量。 |
跳轉到源代碼(Jump to Source) | F4 | 在編輯器中打開該變量或字段所在的源代碼,并將光標定位到對應行。 |
跳轉到類型定義(Jump to Type Source) | F4 | 跳轉到當前變量或字段所屬類的定義位置。 |
查看為(View as) | – | 選擇變量值的顯示格式。 🔹 Hex(十六進制):適用于數值變量。 🔹 Binary(二進制):適用于二進制數據。 |
查看為數組(View as Array) | – | 適用于表示 NumPy 數組的變量。需要在解釋器中安裝 NumPy。也可以點擊變量旁邊的 View as Array 鏈接。 |
查看為圖像(View as Image) | – | 適用于 NumPy 的 1D/2D/3D 數組變量。需要安裝 NumPy 和 Pillow。 |
查看為 DataFrame(View as DataFrame) | – | 適用于表示 pandas DataFrame 的變量。需要在解釋器中安裝 pandas。也可以點擊變量旁邊的 View as DataFrame 鏈接。 |
變量類型
每個變量左側的圖標表示其類型:
:數組
:原始類型
:對象
監視(Watches)
在 Watches 面板 中,你可以在當前調用棧幀的上下文中評估任意數量的變量或表達式。每當程序執行到下一步時,這些表達式的值都會自動更新,并在程序暫停時顯示出來。
雖然你可以通過 Variables 面板 的右鍵菜單使用 “Evaluate Expression(評估表達式)” 來查看某一個表達式的值,但 Watches 面板 可以同時顯示多個表達式,并且在多個調試會話之間保持不變,直到你主動刪除它們。
你可以通過以下方式添加監視表達式:
- 在 Watches 面板 中直接添加
- 在 Variables 面板 中右鍵添加
- 在編輯器中選中表達式并添加
所有監視表達式都會在當前選中的調用棧幀(Frames 面板)的上下文中進行評估。
如果某個表達式無法被評估,其值會顯示為問號 ?
。
默認情況下,Watches 面板是隱藏的,此時監視表達式會直接顯示在 Variables 面板 中。
如果你希望 Watches 面板單獨顯示:
- 點擊調試工具欄中的 Layout Settings(布局設置) 按鈕
- 選擇 Separate Watches(分離顯示監視面板)
這樣就能將監視表達式獨立顯示,便于統一查看和管理。
表達式求值字段(Evaluate expression field)
要評估任意表達式,只需在 Watches 面板 中的 表達式求值字段 輸入表達式并按下 Enter
鍵。
結果會立即顯示在下方。你還可以點擊輸入框右側的圖標,將該表達式添加到監視列表中。
工具欄(Toolbar)
項目 | 快捷鍵 | 描述 |
---|---|---|
插入 | 點擊此按鈕以創建新監視。 | |
Delete | 點擊此按鈕以從列表中移除選定的監視。 | |
| Alt0↑ Alt0↓ | 使用這些按鈕更改監視的順序。 |
Ctrl0D | 使用此按鈕創建選定監視的副本。 | |
在變量選項卡中顯示監視 | 使用此切換按鈕隱藏或顯示 監視 窗格。 默認情況下,該按鈕被按下并顯示在 變量 窗格的工具欄上。 因此, 監視 窗格被隱藏,監視顯示在 變量窗格 中。
|
右鍵菜單(Context menu)
項目 | 快捷鍵 | 描述 |
---|---|---|
新建監視(New Watch) | — | 選擇此命令以創建一個新的監視表達式。將打開一個文本字段用于輸入新的表達式。 |
刪除監視(Remove Watch) | Delete | 刪除當前選中的監視表達式。 |
編輯(Edit) | F2 | 修改當前選中的監視表達式。 |
刪除所有監視(Remove All Watches) | — | 刪除列表中的所有監視表達式。 |
檢查(Inspect) | — | 可用于字段、局部變量和引用表達式,打開一個非模態的檢查窗口,用于專注查看特定引用。你可以打開任意數量的檢查窗口。窗口視圖與 Watches 面板一致,但占用空間更少。 |
顯示引用對象(Show Referring Object) | — | 顯示引用當前監視表達式的所有對象列表。 |
復制值(Copy Value) | Ctrl + C | 復制選中變量的值到剪貼板。如果選中多個項,不僅會復制變量值,還會復制其結構(類似調試器的樹形結構),粘貼到文本文件時有良好縮進格式。 也可以將鼠標懸停在值上,在工具提示中查看內容。 |
復制 JSON(Copy JSON) | — | 僅適用于 JavaScript 環境,將選中的值以 JSON 格式復制。 |
與剪貼板比較值(Compare Value with Clipboard) | — | 將當前值與剪貼板中的值進行比較。 |
復制名稱(Copy Name) | — | 將選中變量的名稱復制到剪貼板。 |
計算表達式(Evaluate Expression) | Alt + F8 | 在彈出的對話框中計算所選變量的表達式。 |
添加到監視(Add to Watches) | — | 可用于除靜態節點外的所有節點。創建一個引用該節點的表達式并添加到 Watches 面板中。 |
顯示引用對象(Show Referring Objects) | — | 顯示當前選中變量被哪些對象引用。 |
跳轉到源代碼(Jump to Source) | F4 | 在編輯器中打開該變量或字段的源代碼,并將光標定位到對應的行。 |
跳轉到類型定義(Jump to Type Source) | F4 | 跳轉到所選變量或字段所屬類的定義處。 |
以其他格式查看(View as) | — | 設置變量值的顯示方式。對于整數類型,可選擇二進制、十進制或十六進制: - Hex:十六進制顯示 - Binary:二進制字面量顯示 |
以數組查看(View as Array) | — | 適用于 NumPy 數組類型的變量。需確保 Python 解釋器中已安裝 NumPy。也可以點擊變量旁的 “View as Array” 鏈接。 |
以圖像查看(View as Image) | — | 適用于 1D/2D/3D 的 NumPy 數組變量。需確保已安裝 NumPy 和 Pillow。 |
以數據表查看(View as DataFrame) | — | 適用于 pandas 數據框類型變量。需確保已安裝 pandas。也可以點擊變量旁的 “View as DataFrame” 鏈接。 |
調試過程
斷點
斷點是特殊的標記,用于在程序執行到特定位置時暫停運行。這樣你就可以檢查程序的狀態和行為。斷點可以很簡單,比如程序執行到某一行代碼時暫停;也可以更復雜,比如根據額外條件判斷是否暫停、寫入日志等操作。
設置斷點后,它會一直保留在你的項目中,除非你主動刪除它,臨時斷點除外。
如果包含斷點的文件被外部修改(例如通過版本控制系統更新或在外部編輯器中更改),且行號發生了變化,斷點會相應地自動調整位置。請注意,此類更改發生時,PyCharm 必須處于運行狀態,否則這些更改將不會被檢測到。
斷點類型
PyCharm 支持以下幾種斷點類型:
-
行斷點:程序執行到設置斷點的代碼行時暫停。此類型斷點可以設置在任何可執行的代碼行上。
-
異常斷點:當拋出 Exception 或其子類時暫停程序。在 PyCharm 中,你可以為 Python 異常設置斷點。對于 PyCharm Professional 版,還支持 Django、Jinja2、JavaScript 和 Jupyter 的異常斷點。這些斷點對異常條件全局生效,不需要特定的源碼位置。與僅查看堆棧跟蹤不同,異常斷點暫停程序時,可以讓你在異常上下文或數據仍然可用時進行檢查。
設置斷點
-
設置行斷點:
點擊可執行代碼行的裝訂區域,設置斷點。 或者,將文本光標放在行上并按下 CtrlF8。
-
設置異常斷點
管理斷點
-
移除斷點
-
靜音斷點:如果您暫時不需要在斷點處暫停,可以將其 靜音。 這使您能夠在不離開調試器會話的情況下恢復正常程序操作。 之后,您可以取消靜音斷點并繼續調試。
點擊 靜音斷點 按鈕
在 調試 工具窗口的工具欄中。
-
啟用/禁用斷點,當您移除斷點時,其 內部配置會丟失。 若要在不丟失斷點參數的情況下暫時關閉單個斷點,您可以 disable 它:
對于非異常斷點:右鍵點擊并根據需要設置 已啟用 選項。 您還可以用中鍵切換它們,如果移除斷點沒有 assigned 到它。
對所有斷點:點擊 運行 | 查看斷點 CtrlShiftF8 ,然后在列表中選中/取消選中斷點。
斷點圖標
根據它們的 類型和 狀態 ,中斷點會被標記以下圖標:
行 | 異常 | |||
---|---|---|---|---|
常規 | ||||
已禁用 | ||||
已驗證 | ||||
靜音 | ||||
非活動/依賴 | ||||
靜音已禁用 | ||||
非掛起 | ||||
已驗證的非掛起 | ||||
無效 |
啟動調試器會話
啟動調試器會話與以正常模式運行程序非常相似。 調試器在后臺附加,因此您無需配置任何特定內容即可開始調試會話。 如果您能夠從 PyCharm 運行您的程序,您也可以使用相同的配置對其進行調試。
檢查掛起的程序
在調試器會話 啟動后, Debug工具窗口會出現,程序會正常運行,直到發生以下情況之一:
-
觸發了一個 breakpoint
-
手動 暫停程序
之后,程序將被掛起,允許用戶檢查其當前狀態、控制其進一步執行并在運行時測試各種場景。
程序的狀態由 frames表示。 當程序暫停時,當前的幀堆棧將顯示在 幀 選項卡中的 調試 工具窗口內。
幀對應于活動的方法或函數調用。 它存儲了被調用方法或函數的局部變量、其參數以及使表達式求值成為可能的代碼上下文。
每次調用 方法 時,都會在棧頂新增一個幀。 當 方法 的執行完成時,相應的幀將從堆棧中移除(最后一個進,最先一個出)。
檢查幀有助于您了解為什么特定參數被傳遞給方法,以及調用者在調用時的狀態。
變量 選項卡顯示所選 幀/線程中的變量列表。 檢查變量可以幫助您理解程序為何以某種方式運行。
如果您想測試程序在特定數據下的行為或在運行時更改其流程,可以通過更改變量值來實現。
PyCharm 允許您在調試會話中評估表達式,以獲取有關程序狀態的更多詳細信息或在運行時測試各種執行場景。
此功能僅在程序在命中斷點后暫停(而非 暫停 )時有效。
指向您要計算的表達式。 表達式的結果顯示在工具提示中。
逐步執行程序
PyCharm 提供了一組單步操作,具體使用取決于您的策略,例如您是需要直接跳到下一行還是檢查中間的方法調用。
使用 PyCharm 進行遠程調試
使用 PyCharm,你可以通過位于另一臺計算機上的解釋器調試你的應用程序,例如,位于 Web 服務器或專用測試機上。
PyCharm 提供兩種遠程調試方式:
-
通過遠程解釋器
- 適用場景:利用遠程機器上更強大的調試功能。
- 要求:本地機器需通過 SSH 訪問遠程服務器。
-
使用 Python 遠程調試服務器配置
- 適用場景:將調試過程集成到遠程服務器上的多個運行進程中。當你無法顯式啟動應用程序進行調試,或者需要進行某些準備工作時,這種方式非常有用。
- 要求:本地機器需通過 SSH 訪問遠程服務器,且遠程服務器需能通過任意預定義端口訪問本地機器。
在此示例中,運行您的應用程序的機器被稱為 local ,而具有遠程解釋器的機器被稱為 remote。
配置遠程解釋器:
將您的應用程序部署到遠程主機:
查看調試輸出。 請注意,調試實際上是在指定的遠程服務器上進行的。
使用調試控制臺
調試控制臺使您能夠查看輸出和錯誤消息。
默認情況下,控制臺是交互式的。 它將顯示提示,您可以使用代碼補全執行命令。
您可以通過點擊 顯示調試控制臺 來禁用此行為。
在控制臺中,您可以:
尾聲
寫到這里,其實我們已經把 PyCharm 的調試功能基本過了一遍。無論是最基礎的斷點設置、變量觀察,還是更高級的表達式求值、遠程調試、查看引用對象等功能,PyCharm 都提供了非常直觀且強大的工具來支持日常開發中的調試工作。
可能一開始你會覺得這些窗口和按鈕有點多、有點亂,但只要你真正開始用起來,比如在調不通的代碼上打個斷點、一步步查看變量值,慢慢你就會意識到這些工具有多香。不用滿屏 print()
,不用瞎猜代碼在哪出錯,整個調試過程就像在看一部代碼的“慢動作電影”,每一幀都能掌控。
更別說遠程調試這個能力了,對于需要部署到服務器、或者跑在 Docker、虛擬機里的項目來說,它簡直就是救命稻草。配置好一次之后,你就可以像本地調試一樣去控制遠程代碼的執行,非常方便。
總之,如果你平時寫 Python 項目,尤其是中大型項目,強烈建議把 PyCharm 的調試工具真正用起來。會調試,遠比只會寫代碼更重要,它能幫你節省大量排查 bug 的時間,也能讓你對程序的執行流程有更深的理解。希望這篇文章能幫你更快上手,也歡迎你繼續去探索更多好用的小技巧!