Python调试器pdb进阶
Python 调试器 pdb 进阶详解pdb 是 Python 标准库内置的调试器无需安装任何第三方工具即可进行断点调试、变量检查和代码步进执行。一、breakpoint() —— Python 3.7 新入口---------------------------------------# Python 3.7 引入的内置函数自动进入调试器def calculate_total(prices: list[float]) - float:total 0.0for i, price in enumerate(prices):# 插入断点程序运行到这里会自动暂停进入 pdbbreakpoint()total pricereturn total# 执行时会在 breakpoint() 处暂停# 自动进入交互式调试环境# 可以通过环境变量控制 breakpoint() 的行为# export PYTHONBREAKPOINT0 # 禁用所有 breakpoint()# export PYTHONBREAKPOINTipdb.set_trace # 使用 ipdb 替代 pdb# breakpoint() 等价于# import pdb; pdb.set_trace()def process_data(items):result []for item in items:# 这是最常用的调试入口写法breakpoint() # 在这里检查 item 的值processed transform(item)result.append(processed)return result二、pdb 常用命令详解--------------------# 进入调试器后可用以下命令单步调试def debug_demo():x 10y 20z x y # 1. 在这里 breakpoint()name Pythondata [1, 2, 3]result {sum: z,name: name,data: data,}return result# n (next) —— 执行下一行代码不进入函数内部# s (step) —— 进入函数内部调试# c (continue) —— 继续执行直到遇到下一个断点# l (list) —— 显示当前行附近的源代码# l 命令示例# (Pdb) l# 1 def debug_demo():# 2 x 10# 3 y 20# 4 z x y# 5 name Python# 6 - data [1, 2, 3] - 当前执行位置# 7 result {# 8 sum: z,# 9 name: name,# 10 data: data,# 11 }# p (print) —— 打印表达式的值# (Pdb) p x# 10# (Pdb) p z# 30# (Pdb) p locals()# {x: 10, y: 20, z: 30, name: Python}# pp (pretty print) —— 美化打印适合复杂数据结构# (Pdb) pp {users: [{id: 1, name: 张三}, {id: 2, name: 李四}]}# {users: [{id: 1, name: 张三}, {id: 2, name: 李四}]}# r (return) —— 运行当前函数直到返回# s (step into) —— 进入函数内部三、条件断点------------# 在特定条件下中断执行def find_user(users: list[dict], target_id: int) - dict | None:for user in users:# 只在 target_id 为 5 时中断breakpoint() # 运行后手动设置条件if user[id] target_id:return userreturn None# 运行后在 pdb 中设置条件断点# (Pdb) condition 1 user[id] 10# 在第 1 个断点设置条件仅当 id 10 时中断# 使用 Python 的 conditional expressionfor i in range(100):# 只在 i 等于 50 时中断if i 50:breakpoint()process(i)# 设置临时断点只中断一次# (Pdb) tbreak 42# 在第 42 行设置临时断点# 清除断点# (Pdb) clear 1 # 清除第 1 个断点# (Pdb) clear # 清除所有断点四、! 命令 —— 执行任意 Python 代码-----------------------------------# ! 前缀允许在 pdb 中执行任意 Python 语句def debug_mutation():data {count: 0, items: []}for i in range(5):breakpoint() # 在这里可以动态修改变量data[count] 1data[items].append(i)return data# 在 pdb 中动态修改变量# (Pdb) !data[count] 100# (Pdb) !data[items].extend([10, 20, 30])# (Pdb) !print(修改后:, data)# (Pdb) p data# {count: 100, items: [0, 10, 20, 30]}# 临时测试函数调用# (Pdb) !import math# (Pdb) !result math.sqrt(42)# (Pdb) p result# 6.48074069840786# 调用项目中的函数# (Pdb) !validate_data(data)五、post-mortem 调试--------------------# 在程序崩溃后自动进入调试器检查异常现场import tracebackimport sysdef buggy_function():# 这个函数会抛出异常x 10y 0result x / y # ZeroDivisionErrorreturn resulttry:buggy_function()except Exception:# 捕获异常后进入 post-mortem 调试import pdbtraceback.print_exc()pdb.post_mortem()# post_mortem 会在异常发生的帧处进入 pdb# 可以检查所有局部变量和调用栈# 更方便的方式使用 pdb.pm()# python -m pdb script.py 运行脚本异常时进入调试# 使用 pdb 运行整个脚本异常时自动进入调试# python -m pdb my_script.py# 然后在 pdb 中输入 c继续执行# 遇到未捕获异常时自动进入 post-mortem 模式六、调用栈管理--------------# 在多层调用中导航def outer():x 外层变量middle()def middle():y 中层变量inner()def inner():z 内层变量breakpoint() # 在这里暂停print(f{z})# 调用栈操作命令# w (where) —— 显示当前调用栈# (Pdb) w# inner() - breakpoint()# middle() - inner()# outer() - middle()# - outer()# u (up) —— 向上移动到调用栈的上层帧# (Pdb) u# 移动到 middle() 的帧可以访问变量 y# d (down) —— 向下移动到调用栈的下层帧# (Pdb) d# 回到 inner() 的帧# 在不同帧中可以打印不同层的局部变量# (Pdb) p x# 外层变量七、实用调试技巧----------------# 1. 设置断点并自动执行命令import pdbdef debug_init():# 启动时即进入调试pdb.set_trace()print(调试开始)# 启动命令文件debug_commands.txt# n# p locals()# c# python -m pdb script.py -c debug_commands.txt# 2. 使用 PYTHONBREAKPOINT 环境变量# export PYTHONBREAKPOINTweb_pdb.set_trace# 3. 远程调试import pdbdef remote_debug():# 结合 socket 实现远程调试import sockethost 0.0.0.0port 12345print(f等待远程调试连接: {host}:{port})# 使用 rpdb 或 web-pdb 实现# pdb 虽简单但功能完整作为 Python 标准库调试器# 在任何环境中都可使用是排查问题的最后防线。