使用pdb进行python代码调试

pdb为python程序实现了一个交互式调试环境。它包括一些特性,可以暂停程序,查看变量值,以及逐步监视程序执行,从而能了解程序具体做了什么,并查找逻辑中存在的bug。

下面结合具体的实例讲述如何使用 pdb 进行调试。

清单 1. 测试代码示例

import pdb
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = a + b + c
print final

开始调试:直接运行脚本,会停留在 pdb.set_trace() 处,选择 n+enter 可以执行当前的 statement。在第一次按下了 n+enter 之后可以直接按 enter 表示重复执行上一条 debug 命令。

清单 2. 利用 pdb 调试

[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb)
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 -> final = a + b + c
7 print final
[EOF]
(Pdb)
[EOF]
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb)

退出 debug:使用 quit 或者 q 可以退出当前的 debug,但是 quit 会以一种非常粗鲁的方式退出程序,其结果是直接 crash。

清单 3. 退出 debug

[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) q
Traceback (most recent call last):
File "epdb1.py", line 5, in ?
c = "ccc"
File "epdb1.py", line 5, in ?
c = "ccc"
File "/usr/lib64/python2.4/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib64/python2.4/bdb.py", line 67, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit

打印变量的值:如果需要在调试过程中打印变量的值,可以直接使用 p 加上变量名,但是需要注意的是打印仅仅在当前的 statement 已经被执行了之后才能看到具体的值,否则会报 NameError: 错误。

清单 4. debug 过程中打印变量

[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) p b
'bbb'
(Pdb)
'bbb'
(Pdb) n
> /root/epdb1.py(6)?()
-> final = a + b + c
(Pdb) p c
'ccc'
(Pdb) p final
*** NameError:
(Pdb) n
> /root/epdb1.py(7)?()
-> print final
(Pdb) p final
'aaabbbccc'
(Pdb)

使用 c 可以停止当前的 debug 使程序继续执行。如果在下面的程序中继续有 set_statement() 的申明,则又会重新进入到 debug 的状态,读者可以在代码 print final 之前再加上 set_trace() 验证。

清单 5. 停止 debug 继续执行程序

[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) n
> /root/epdb1.py(5)?()
-> c = "ccc"
(Pdb) c
aaabbbccc

显示代码:在 debug 的时候不一定能记住当前的代码块,如要要查看具体的代码块,则可以通过使用 list 或者 l 命令显示。list 会用箭头 -> 指向当前 debug 的语句。

清单 6. debug 过程中显示代码

[root@rcc-pok-idg-2255 ~]# python epdb1.py
> /root/epdb1.py(4)?()
-> b = "bbb"
(Pdb) list
1 import pdb
2 a = "aaa"
3 pdb.set_trace()
4 -> b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 print final
[EOF]
(Pdb) c
> /root/epdb1.py(8)?()
-> print final
(Pdb) list
3 pdb.set_trace()
4 b = "bbb"
5 c = "ccc"
6 final = a + b + c
7 pdb.set_trace()
8 -> print final
[EOF]
(Pdb)

在使用函数的情况下进行 debug

清单 7. 使用函数的例子

import pdb
def combine(s1,s2): # define subroutine combine, which...
s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
s3 = '"' + s3 +'"' # encloses it in double quotes,...return s3 # and returns it.
a = "aaa"
pdb.set_trace()
b = "bbb"
c = "ccc"
final = combine(a,b)
print final

如果直接使用 n 进行 debug 则到 final=combine(a,b) 这句的时候会将其当做普通的赋值语句处理,进入到 print final。如果想要对函数进行 debug 如何处理呢 ? 可以直接使用 s 进入函数块。函数里面的单步调试与上面的介绍类似。如果不想在函数里单步调试可以在断点处直接按 r 退出到调用的地方。

清单 8. 对函数进行 debug

[root@rcc-pok-idg-2255 ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) n
> /root/epdb2.py(11)?()
-> c = "ccc"
(Pdb) n
> /root/epdb2.py(12)?()
-> final = combine(a,b)
(Pdb) s
--Call--
> /root/epdb2.py(3)combine()
-> def combine(s1,s2): # define subroutine combine, which...
(Pdb) n
> /root/epdb2.py(4)combine()
-> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
(Pdb) list
1 import pdb
2
3 def combine(s1,s2): # define subroutine combine, which...
4 -> s3 = s1 + s2 + s1 # sandwiches s2 between copies of s1, ...
5 s3 = '"' + s3 +'"' # encloses it in double quotes,...return s3 # and returns it.
7
8 a = "aaa"
9 pdb.set_trace()
10 b = "bbb"
11 c = "ccc"
(Pdb) n
> /root/epdb2.py(5)combine()
-> s3 = '"' + s3 +'"' # encloses it in double quotes,...
(Pdb) n
> /root/epdb2.py(6)combine()
-> return s3 # and returns it.
(Pdb) n
--Return--
> /root/epdb2.py(6)combine()->'"aaabbbaaa"'
-> return s3 # and returns it.
(Pdb) n
> /root/epdb2.py(13)?()
-> print final
(Pdb)

在调试的时候动态改变值 。在调试的时候可以动态改变变量的值,具体如下实例。需要注意的是下面有个错误,原因是 b 已经被赋值了,如果想重新改变 b 的赋值,则应该使用! B。

清单 9. 在调试的时候动态改变值

[root@rcc-pok-idg-2255 ~]# python epdb2.py
> /root/epdb2.py(10)?()
-> b = "bbb"
(Pdb) var = "1234"
(Pdb) b = "avfe"
*** The specified object '= "avfe"' is not a function
or was not found along sys.path.
(Pdb) !b="afdfd"
(Pdb)

pdb 调试有个明显的缺陷就是对于多线程,远程调试等支持得不够好,同时没有较为直观的界面显示,不太适合大型的 python 项目。而在较大的 python 项目中,这些调试需求比较常见,因此需要使用更为高级的调试工具。接下来将介绍 PyCharm IDE 的调试方法 .

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/219885.html<

(0)
运维的头像运维
上一篇2025-04-14 07:50
下一篇 2025-04-14 07:52

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注