pdb 的具体使用方法

pdb 是 Python 自带的交互式命令行调试器,可以让你在任意位置暂停程序、逐行执行、查看和修改变量、设置断点等。下面从 启动方式常用命令完整案例 三部分详解。


一、启动 pdb 的三种方式

1. 命令行直接运行脚本(从第一行开始调试)
python -m pdb my_script.py

程序会在第一行代码处暂停,进入 pdb 交互模式。

2. 在代码中插入 breakpoint()(Python 3.7+)或 pdb.set_trace()
import pdb

def my_func():
    x = 10
    breakpoint()      # 程序运行到这里会自动暂停,进入 pdb
    y = x * 2
    return y

my_func()

运行脚本(python my_script.py),遇到 breakpoint() 就会暂停。
Python 3.6 及以下需使用 pdb.set_trace()

3. 事后调试(程序异常崩溃时自动进入 pdb)
python -m pdb -c continue my_script.py

或者先运行脚本,发生未捕获异常后,用 pdb.pm() 进入事后调试:

import pdb
try:
    1/0
except:
    pdb.pm()   # 进入异常发生时的上下文

二、pdb 常用命令(核心)

命令(缩写) 完整写法 作用
h help 显示帮助,h <command> 查看具体命令帮助
l list 显示当前代码周围的 11 行,l . 显示当前行,l 10,15 显示 10-15 行
n next 执行下一行(不进入函数内部)
s step 执行下一行,如果是函数则进入函数内部
c continue 继续运行直到下一个断点或程序结束
q quit 退出调试器,程序终止
p <expr> print 打印表达式的值,如 p x+y
pp <expr> pp 美观打印(pretty-print),适合字典/列表
whatis <var> - 显示变量的类型
b break 列出所有断点
b <line> break 在当前文件的指定行设置断点,如 b 15
b <file:line> - 在其他文件设置断点,如 b module.py:20
b <function> - 在函数入口设置断点,如 b my_function
b <line>, <condition> - 条件断点,如 b 20, x>5
tbreak temporary break 临时断点(命中一次后自动删除)
cl clear 清除断点,cl 1 删除编号为1的断点,cl 删除所有断点
disable <bpnum> - 禁用断点,如 disable 2
enable <bpnum> - 重新启用断点
ignore <bpnum> <count> - 忽略断点前 count 次命中
condition <bpnum> <expr> - 为已有断点添加条件,如 condition 1 x==100
j <line> jump 跳转到指定行执行(跳过部分代码)
r return 执行到当前函数返回
u / d up / down 在调用栈中向上/向下移动(查看上层调用者)
w where 打印当前调用栈(显示调用顺序)
a args 打印当前函数的参数
!<stmt> - 执行 Python 语句,如 !x=100(修改变量)
interact - 启动交互式 Python shell(可在其中执行多行代码)

提示:大部分命令支持回车重复上一次命令(例如连续按 n 可以逐行执行)。


三、完整案例演示

假设有一个求平均数的函数,但传入空列表时会报错。我们用 pdb 来定位问题。

# average.py
def calculate_average(numbers):
    total = sum(numbers)
    count = len(numbers)
    average = total / count   # 如果 count=0 会触发 ZeroDivisionError
    return average

def main():
    data = []
    result = calculate_average(data)
    print(f"平均值是: {result}")

if __name__ == "__main__":
    main()
调试过程(使用 breakpoint() 方式)
  1. 在可疑位置插入 breakpoint()
    修改 average.py

    def calculate_average(numbers):
        total = sum(numbers)
        count = len(numbers)
        breakpoint()               # 加入断点
        average = total / count
        return average
    
  2. 运行脚本

    python average.py
    

    程序暂停,进入 pdb 交互界面,显示当前行和箭头:

    > /home/user/average.py(5)calculate_average()
    -> average = total / count
    (Pdb)
    
  3. 查看当前变量

    (Pdb) p total
    0
    (Pdb) p count
    0
    (Pdb) whatis count
    <class 'int'>
    
  4. 单步执行并捕获异常

    (Pdb) n   # 执行当前行
    ZeroDivisionError: division by zero
    > /home/user/average.py(5)calculate_average()
    -> average = total / count
    

    异常抛出后,pdb 会停在该行。此时可以查看调用栈:

    (Pdb) w
      /home/user/average.py(12)<module>()
    -> main()
      /home/user/average.py(9)main()
    -> result = calculate_average(data)
    > /home/user/average.py(5)calculate_average()
    -> average = total / count
    
  5. 修改变量并继续执行
    我们临时把 count 改为 1,避免除零:

    (Pdb) !count = 1
    (Pdb) p count
    1
    (Pdb) n          # 再次执行
    --Return--
    > /home/user/average.py(5)calculate_average()->0.0
    -> average = total / count
    (Pdb) p average
    0.0
    (Pdb) c          # 继续运行
    平均值是: 0.0
    
  6. 退出 pdb

    (Pdb) q
    
另一种调试:设置条件断点

假设循环中只关心 i == 5 的情况,可以用条件断点:

for i in range(10):
    breakpoint()   # 可替换为条件断点,但 pdb 原生支持 b 行号,条件

更好的做法:

# 在循环前加断点,然后在 pdb 中设置
(Pdb) b 10, i==5    # 假设循环体在第10行
(Pdb) c             # 继续运行,直到 i==5 时暂停

四、高效技巧

  • 自动补全:按 Tab 键可以补全变量名或命令。
  • 别名:可以为常用命令设置别名,如 alias nxt next
  • 调试脚本pdb.run('function(arg)') 可在代码中直接调试表达式。
  • 远程调试:结合 pdb.Pdb 类实现 socket 远程调试(较复杂,一般用 IDE 替代)。

五、pdb 与 VS Code 调试对比

特性 pdb VS Code
上手难度 需记忆命令 图形化,点击即可
变量查看 命令行 p var 鼠标悬停、变量面板
条件断点 命令行 b 10, x>5 右键设置,图形输入
远程调试 支持(需手动实现) 原生支持(attach)
日志点 支持
环境依赖 任何终端 需要 VS Code + 插件

结论

  • 在远程服务器、无图形界面环境、或需要快速轻量调试时,pdb 是首选
  • 在日常本地开发中,VS Code 图形化调试更高效,但理解 pdb 能帮助你深入理解调试原理,并且在任何 Python 环境下都能救命。

掌握 pdb 的核心命令(n, s, c, p, b, q)就足以应对 80% 的命令行调试场景。遇到复杂问题时,再查阅 help 即可。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐