Ubuntu 上调试 Python 的方式很多,真正影响效率的往往不是“会不会调试”,而是遇到不同问题时能不能迅速选对工具。本文按从轻到重的使用路径整理常见方案:先看最容易上手的 pdb 和 IDE 调试器,再到 ipdb、PySnooper、logging、assert,最后补充 C 扩展场景下的 gdb。读完后,你可以根据“临时排查、图形化单步、长期日志记录、底层崩溃定位”这几类需求,判断哪种方法最合适。
先用内置 pdb 做命令行排查
如果你在 Ubuntu 服务器、本地终端或临时脚本里排查问题,pdb 往往是启动成本最低的选择。它是 Python 标准库自带调试器,不需要额外安装,适合快速停住程序、查看变量和单步执行。
最常见的用法是在目标位置插入下面这行代码:
import pdb; pdb.set_trace()
程序运行到这里后,会进入交互式调试状态,等待你输入命令。
pdb 常用命令
l:显示当前行及周围代码;n:执行下一行,但不进入函数内部;s:单步进入函数调用;c:继续执行,直到下一个断点;p <变量名>:打印变量值;q:退出调试器。
pdb 是纯文本交互,没有语法高亮,也没有图形面板,但它的优势也很明确:轻量、零依赖、远程环境可直接使用。对线上复现、容器内部排查、SSH 登录后的临时调试,这类方式通常最省事。
需要可视化时,直接用 IDE 调试器
如果问题涉及多层调用、变量状态频繁变化,或者你更依赖图形界面,那么 IDE 自带调试器会明显更高效。它的优势在于断点、调用栈、变量面板和单步控制都集中在一个界面里,不需要频繁手输命令。

PyCharm:安装后即可配置断点调试
Ubuntu 上可以直接安装 PyCharm 社区版:
snap install pycharm-community --classic
打开项目后,先在右上角点击“Add Configuration”,选择“Python”,配置脚本路径和工作目录。接着在代码行号旁边点击设置断点,再点击工具栏上的调试按钮,程序就会在断点处暂停。
进入调试后,可以重点使用这些信息:
- 变量面板:查看当前作用域中的变量值;
- 调用栈:确认函数是从哪一层进入当前断点的;
- 单步按钮:继续、跳过、进入函数等操作更直观。
如果你平时就在 PyCharm 里写 Python,直接使用内置调试能力通常是最顺手的方案。
VS Code:用 launch.json 配好当前文件调试
VS Code 适合更轻量的图形化开发环境。前提是先安装 Microsoft 官方 Python 扩展,然后在项目根目录下创建 .vscode/launch.json。
一个常见配置如下:
{"version": "0.2.0","configurations": [{"name": "Python: Current File","type": "python","request": "launch","program": "${file}","console": "integratedTerminal"}]}
完成配置后,就可以像 PyCharm 一样,在行号区域设置断点,点击左侧调试图标,再点击绿色“开始调试”按钮进入调试流程。
这类方式适合本地项目开发、需要图形化观察变量,又不想切换到更重型 IDE 的用户。
嫌原生工具不够顺手,可以换增强调试方案
有些问题并不需要完整 IDE,但原生 pdb 又显得太朴素。这时可以考虑两个方向:一个是保留交互式断点体验但改善界面,另一个是自动记录执行过程,减少手工插桩。
ipdb:保留 pdb 用法,补上交互体验
ipdb 可以理解为增强版 pdb,它提供语法高亮、自动补全等能力,使用习惯与 pdb 基本一致。
安装命令:
pip install ipdb
把原来的断点语句替换为:
import ipdb; ipdb.set_trace()
如果你已经熟悉 pdb 命令,但希望交互体验更清晰,ipdb 往往是最直接的升级。
PySnooper:自动记录函数每一步变化
PySnooper 适合另一类场景:你不一定想手动单步执行,但希望看到函数每一行是怎么跑的、变量如何变化。它会自动输出执行日志,尤其适合分析复杂函数逻辑。
安装命令:
pip install pysnooper
基本用法是在目标函数前添加装饰器:
@pysnooper.snoop()
运行程序后,控制台会输出执行行号、变量值变化以及相关代码片段。相比传统 print(),它更系统;相比 IDE 单步调试,它更适合回放式分析。
需要长期保留信息时,用 logging;快速校验时,用 assert
调试并不总是为了“停住程序”。在很多项目里,真正有价值的是持续记录运行状态,或者在关键位置快速验证输入条件。这两类需求更适合用 logging 和 assert 来处理。

logging:把调试信息变成可保留的结构化日志
logging 是标准库自带模块,不需要单独安装。它适合记录函数输入、关键分支、异常前状态等信息,而且可以长期保留到文件或其他输出目标中。
下面是原文中的示例:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
def divide(a, b):
logging.debug(f'Dividing {a} by {b}')
return a / b
result = divide(10, 2)
运行后会得到类似输出:
2025-09-25 10:00:00 - DEBUG - Dividing 10 by 2
它的优势不在于“停住看变量”,而在于把关键状态持续写下来。对于服务端程序、批处理任务和需要回溯问题的项目,这通常比临时断点更实用。
assert:用最短路径验证关键假设
如果你只是想快速确认某个条件是否成立,不一定要上调试器。assert 可以在条件不满足时立即抛出 AssertionError,并显示你提供的提示信息。
例如:
def calculate_discount(price, discount):
assert discount >= 0 and discount <= 1, "Discount must be between 0 and 1"
return price * (1 - discount)
result = calculate_discount(100, 1.5) # 触发AssertionError
它适合表达“这里本来就应该满足某个内部假设”。但要注意,assert 在使用 -O 参数启动 Python 时可能被优化掉,所以不应把它当成生产环境里的正式数据校验手段。
涉及 C/C++ 扩展时,要切换到 gdb
如果问题已经超出纯 Python 层,比如程序使用了 Cython 或其他 C/C++ 扩展模块,pdb、IDE 调试器这类工具就很难继续深入。这时要使用 gdb 结合 Python 调试信息定位问题。
先安装相关工具:
sudo apt-get install gdb python-dbg
然后找到目标 Python 进程的 PID,通过下面的命令附加:
sudo gdb -p
进入 gdb 后,可以结合两组调用栈信息:
py-bt:查看 Python 层调用栈;bt:查看 C 层调用栈。
把这两部分信息对照起来,通常就能判断问题出在 Python 调用链、扩展边界,还是更底层的 C 代码内部。
怎么选:按问题场景匹配工具就够了
如果你只是临时停下来看看变量,优先用 pdb;如果需要图形化断点、变量面板和调用栈,直接用 PyCharm 或 VS Code;如果想保留 pdb 习惯但改善体验,用 ipdb;如果要自动观察函数执行过程,试试 PySnooper;如果目标是长期记录状态,应该换成 logging;如果只是验证内部假设,assert 足够直接;而一旦问题进入 C 扩展层面,就要切到 gdb。
换句话说,Ubuntu 上调试 Python 并不存在单一“最佳工具”,关键是先判断你面对的是哪一种问题,再选择最省成本的定位路径。







