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中exit、return、sys.exit()等使用实例和区别
May 28 Python
Python工程师面试题 与Python Web相关
Jan 14 Python
Python常用的内置序列结构(列表、元组、字典)学习笔记
Jul 08 Python
pandas or sql计算前后两行数据间的增值方法
Apr 20 Python
tensorflow实现加载mnist数据集
Sep 08 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
Oct 30 Python
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
Dec 18 Python
Python写出新冠状病毒确诊人数地图的方法
Feb 12 Python
Keras自动下载的数据集/模型存放位置介绍
Jun 19 Python
python字典key不能是可以是啥类型
Aug 04 Python
Python如何解除一个装饰器
Aug 07 Python
手把手教你使用TensorFlow2实现RNN
Jul 15 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
Flash空降上海 化身大魔王接受挑战
2020/03/02 星际争霸
php命名空间学习详解
2014/02/27 PHP
destoon找回管理员密码的方法
2014/06/21 PHP
PHP基于工厂模式实现的计算器实例
2015/07/16 PHP
php中的抽象方法和抽象类
2017/02/14 PHP
php实现批量上传数据到数据库(.csv格式)的案例
2017/06/18 PHP
由Javascript实现的页面日历
2011/11/04 Javascript
ajax上传时参数提交不更新等相关问题
2012/12/11 Javascript
javascript jscroll模拟html元素滚动条
2012/12/18 Javascript
JQuery点击事件回到页面顶部效果的实现代码
2016/05/24 Javascript
功能强大的Bootstrap组件(结合js)
2016/08/03 Javascript
JavaScript中数据类型转换总结
2016/12/25 Javascript
bootstrap 表单验证使用方法
2017/01/11 Javascript
微信小程序 判断手机号的实现代码
2017/04/19 Javascript
Require.JS中的几种define定义方式示例
2017/06/01 Javascript
React组件之间的通信的实例代码
2017/06/27 Javascript
使用jQuery实现购物车结算功能
2017/08/15 jQuery
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
JS实现访问DOM对象指定节点的方法示例
2018/04/04 Javascript
详解Angular6 热加载配置方案
2018/08/18 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
vant 中van-list的用法说明
2020/11/11 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
Python实现的ini文件操作类分享
2014/11/20 Python
Python笔记之观察者模式
2019/11/20 Python
使用Python发现隐藏的wifi
2020/03/04 Python
Python爬虫抓取论坛关键字过程解析
2020/10/19 Python
python实现双人五子棋(终端版)
2020/12/30 Python
python解包用法详解
2021/02/17 Python
介绍一下Python下range()函数的用法
2013/11/07 面试题
四年的个人工作自我评价
2013/12/10 职场文书
小区门卫工作职责
2013/12/14 职场文书
Python基础详解之邮件处理
2021/04/28 Python
Python中如何处理常见报错
2022/01/18 Python
详解Flutter和Dart取消Future的三种方法
2022/04/07 Java/Android