python的debug实用工具 pdb详解


Posted in Python onJuly 12, 2019

叨逼叨

首先,介绍一下 pdb 调试,pdb 是 python 的一个内置模块,用于命令行来调试 Python 代码。或许你会说,现在用 Pycharm 等编辑器来调试代码很方便,为啥要用命令行呢?这个问题,我曾经也这么想,直到有一次,代码必须要在 Linux 系统上跑(现在 Pycharm 也可以远程调试代码了,今天先不说这个)

使用介绍

如何添加断点?

说到 debug,肯定是要添加断点的,这里有两种方式添加断点:

在想要断点代码后添加 一行

pdb.set_trace()

若是使用这种方式,直接运行 Python 文件即可进入断点调试。

用命令行来添加断点

b line_number(代码行数)

若是使用这种方式,需要 python -m pdb xxx.py 来启动断点调试。

常用命令

先简单介绍一下使用命令,这里不用记住,等用到的时候回来查就行。

1 进入命令行Debug模式,python -m pdb xxx.py

2 h: (help)帮助

3 w: (where)打印当前执行堆栈

4 d: (down)执行跳转到在当前堆栈的深一层(个人没觉得有什么用处)

5 u: (up)执行跳转到当前堆栈的上一层

6 b: (break)添加断点

  • b 列出当前所有断点,和断点执行到统计次数
  • b line_no:当前脚本的line_no行添加断点
  • b filename:line_no:脚本filename的line_no行添加断点
  • b function:在函数function的第一条可执行语句处添加断点

7 tbreak: (temporary break)临时断点

在第一次执行到这个断点之后,就自动删除这个断点,用法和b一样

8 cl: (clear)清除断点

  • cl 清除所有断点
  • cl bpnumber1 bpnumber2... 清除断点号为bpnumber1,bpnumber2...的断点
  • cl lineno 清除当前脚本lineno行的断点
  • cl filename:line_no 清除脚本filename的line_no行的断点

9 disable:停用断点,参数为bpnumber,和cl的区别是,断点依然存在,只是不启用

10 enable:激活断点,参数为bpnumber

11 s: (step)执行下一条命令

如果本句是函数调用,则s会执行到函数的第一句
12 n: (next)执行下一条语句

如果本句是函数调用,则执行函数,接着执行当前执行语句的下一条。
13 r: (return)执行当前运行函数到结束

14 c: (continue)继续执行,直到遇到下一条断点

15 l: (list)列出源码

  • l 列出当前执行语句周围11条代码
  • l first 列出first行周围11条代码
  • l first second 列出first--second范围的代码,如果second<first,second将被解析为行数

16 a: (args)列出当前执行函数的函数

17 p expression:(print)输出expression的值

18 pp expression:好看一点的p expression

19 run:重新启动debug,相当于restart

20 q:(quit)退出debug

21 j lineno:(jump)设置下条执行的语句函数

只能在堆栈的最底层跳转,向后重新执行,向前可直接执行到行号

22)unt:(until)执行到下一行(跳出循环),或者当前堆栈结束

23)condition bpnumber conditon,给断点设置条件,当参数condition返回True的时候bpnumber断点有效,否则bpnumber断点无效

举个简单的栗子

为了验证一下 pdb 的用法,我写了个简单的 Python 代码,如下:

__author__ = 'zone'
__gzh__ = '公号:zone7'
import pdb
class MyScrapy:
 urls = []
 def start_url(self, urls):
 pdb.set_trace()
 for url in urls:
 print(url)
 self.urls.append(url)
 def parse(self):
 pdb.set_trace()
 for url in self.urls:
 result = self.request_something(url)
 def request_something(self, url):
 print('requesting...')
 data = '''<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
</body>
</html>'''
 return data
scrapy= MyScrapy()
scrapy.start_url(["http://www.zone7.cn", "http://www.zone7.cn", "http://www.zone7.cn", "http://www.zone7.cn", ])
scrapy.parse()

运行实例:(这里为了方便大家阅读,我添加了中文注释,实际运行时不会有注释的)

D:workenvScriptspython.exe D:/work_test/test/pdb_test/pdb_test.py
> d:work_test	estpdb_testpdb_test.py(11)start_url()
-> for url in urls:
(Pdb) n 注释:n(next)执行下一步
> d:work_test	estpdb_testpdb_test.py(12)start_url()
-> print(url)
(Pdb) l 注释: l(list)列出当前代码
 7 	 urls = []
 8 	
 9 	 def start_url(self, urls):
 10 	 pdb.set_trace()
 11 	 for url in urls:
 12 ->	 print(url)
 13 	 self.urls.append(url)
 14 	
 15 	 def parse(self):
 16 	 pdb.set_trace()
 17 	 for url in self.urls:
(Pdb) c 注释:c(continue),继续执行,知道遇到下一个断点
http://www.zone7.cn
http://www.zone7.cn
http://www.zone7.cn
http://www.zone7.cn
> d:work_test	estpdb_testpdb_test.py(17)parse()
-> for url in self.urls:
(Pdb) n 注释:n(next)执行下一步
> d:work_test	estpdb_testpdb_test.py(18)parse()
-> result = self.request_something(url)
(Pdb) l 注释: l(list)列出当前代码
 13 	 self.urls.append(url)
 14 	
 15 	 def parse(self):
 16 	 pdb.set_trace()
 17 	 for url in self.urls:
 18 ->	 result = self.request_something(url)
 19 	
 20 	 def request_something(self, url):
 21 	 print('requesting...')
 22 	 data = '''<!DOCTYPE html>
 23 	<html lang="en">
(Pdb) s 注释: s(step)这里是进入 request_something() 函数的意思
--Call--
> d:work_test	estpdb_testpdb_test.py(20)request_something()
-> def request_something(self, url):
(Pdb) n 注释:n(next)执行下一步
> d:work_test	estpdb_testpdb_test.py(21)request_something()
-> print('requesting...')
(Pdb) l 注释: l(list)列出当前代码
 16 	 pdb.set_trace()
 17 	 for url in self.urls:
 18 	 result = self.request_something(url)
 19 	
 20 	 def request_something(self, url):
 21 ->	 print('requesting...')
 22 	 data = '''<!DOCTYPE html>
 23 	<html lang="en">
 24 	<head>
 25 	 <meta charset="UTF-8">
 26 	 <title>Title</title>
(Pdb) p url 注释:p(print)打印出 url 变量的数据
'http://www.zone7.cn'
(Pdb) n 注释:n(next)执行下一步
requesting...
> d:work_test	estpdb_testpdb_test.py(31)request_something()
-> </html>'''
(Pdb) p data 注释:p(print)打印出指定变量的数据,这里由于赋值还没完成,所以报错
*** NameError: name 'data' is not defined
(Pdb) n 注释:n(next)执行下一步
> d:work_test	estpdb_testpdb_test.py(32)request_something()
-> return data
(Pdb) p data 注释:p(print)打印出指定变量的数据
'<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>

</body>
</html>'
(Pdb) q 注释:q(quit)退出

总结

按照上面的例子一套下来,基本的用法就可以学会了,关键还是得自己多实践,动手操练!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
实例讲解Python中的私有属性
Aug 21 Python
仅用500行Python代码实现一个英文解析器的教程
Apr 02 Python
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
Apr 11 Python
深入解读Python解析XML的几种方式
Feb 16 Python
Python数组定义方法
Apr 13 Python
教你用Python脚本快速为iOS10生成图标和截屏
Sep 22 Python
django2用iframe标签完成网页内嵌播放b站视频功能
Jun 20 Python
pyQt4实现俄罗斯方块游戏
Jun 26 Python
Python tkinter label 更新方法
Oct 11 Python
django之自定义软删除Model的方法
Aug 14 Python
Python 中的 import 机制之实现远程导入模块
Oct 29 Python
Python猫眼电影最近上映的电影票房信息
Sep 18 Python
Flask配置Cors跨域的实现
Jul 12 #Python
python调用webservice接口的实现
Jul 12 #Python
python3模拟实现xshell远程执行liunx命令的方法
Jul 12 #Python
Python实现蒙特卡洛算法小实验过程详解
Jul 12 #Python
教你如何编写、保存与运行Python程序的方法
Jul 12 #Python
如何不用安装python就能在.NET里调用Python库
Jul 12 #Python
python 执行终端/控制台命令的例子
Jul 12 #Python
You might like
PHP下的Oracle客户端扩展(OCI8)安装教程
2014/09/10 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
FusionCharts图表显示双Y轴双(多)曲线
2012/11/22 Javascript
js实现杯子倒水问题自动求解程序
2013/03/25 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
js带缩略图的图片轮播效果代码分享
2015/09/14 Javascript
jQuery图片轮播功能实例代码
2017/01/29 Javascript
JS表单验证方法实例小结【电话、身份证号、Email、中文、特殊字符、身份证号等】
2017/02/14 Javascript
手把手搭建安装基于windows的Vue.js运行环境
2017/06/12 Javascript
javascript 日期相减-在线教程(附代码)
2017/08/17 Javascript
微信小程序 scroll-view实现锚点滑动的示例
2017/12/06 Javascript
JavaScript中关于base64的一些事
2019/05/06 Javascript
JS实现导航栏楼层特效
2020/01/01 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
在Echarts图中给坐标轴加一个标识线markLine
2020/07/20 Javascript
[01:45]亚洲邀请赛互动指南虚拟物品介绍
2015/01/30 DOTA
Python实现的多线程同步与互斥锁功能示例
2017/11/30 Python
python实现京东秒杀功能
2018/07/30 Python
值得收藏,Python 开发中的高级技巧
2018/11/23 Python
python安装scipy的方法步骤
2019/06/26 Python
美国杂志订阅折扣与优惠网站:Magazines.com
2016/08/31 全球购物
用C或者C++语言实现SOCKET通信
2015/02/24 面试题
师范应届生教师求职信
2013/11/05 职场文书
给男朋友的道歉信
2014/01/12 职场文书
爱岗敬业演讲稿范文
2014/01/14 职场文书
《藏戏》教学反思
2014/02/11 职场文书
班主任评语大全
2014/04/26 职场文书
优秀学生党员先进事迹材料
2014/05/29 职场文书
医院节能减排方案
2014/06/13 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
工作期间打牌检讨书范文
2014/11/20 职场文书
2015年学校财务工作总结
2015/05/19 职场文书
庆祝教师节新闻稿
2015/07/17 职场文书
2016年学校综治宣传月活动总结
2016/03/16 职场文书
Win10 和 Win11可以共存吗? win10/11产品生命周期/服务更新介绍
2021/11/21 数码科技
navicat 连接Ubuntu虚拟机的mysql的操作方法
2022/04/02 MySQL