python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)

python高级调试技巧(一)——原生态的pdb调试

目录

一 使用系统自带的pdb模式模块进行单

步调试

二 使用set_trace()设置断点

三 pdb模块方法详解

四 使用ipython和jupyter notebook

进行调试(下篇预告)

声明:本文所讲的调试是指不附带任何工具的调试,我们平时使用vs code,pycharm进行调试,包括设置断点、单步执行、多步执行等操作都是IDE设置好的,本文不考虑这些,使用原生态的python调试器,不需要任何IDE开发环境。pdb是python自带的调试器,是python debugger 的简称。使用pdb调试有两种方式。

本次文章依然是分为系列文章进行讲解,本文为系列文章第一篇。

01

使用系统自带的pdb模式模块进行单

步调试

所谓的单步调试,就是指的是每次执行一句Python语句。 单步执行代码,通过在用户终端命令 python -m pdb xxx.py 启动脚本,进入单步执行模式。注意在终端命令输入的前面,会有这样一个显示:

(Pdb),这就表示进入了pdb命令调试。然后输入下面的命令即可。

注意:我们经常看见在python代码中会有 import pdb 这样的语句,但是这样的“单步执行模式”,是不需要在代码里面添加这句话的,当然添加也可以。

pdb命令行:

1)进入命令行Debug模式,python -m pdb xxx.py 这个格式是固定的

之所以可以这样做,主要是因为pdb.py 可以被当做一个脚本script执行。

2)h:(help)帮助

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

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

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

6)b:(break)添加断点

b 列出当前所有断点,和断点执行到统计次数

b line_number:当前脚本的line_no行添加断点

b filename:line_number:脚本filename的line_no行添加断点

b function:在函数function的第一条可执行语句处添加断点

7)tbreak:(temporary break)临时断点

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

8)cl:(clear)清除断点

cl 清除所有断点

cl bpnumber1 bpnumber2... 清除断点号为bpnumber1,bpnumber2...的断点

cl line_number 清除当前脚本line_number行的断点

cl filename:line_number 清除脚本filename的line_number行的断点

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

10)enable:激活断点,参数为bpnumber(即哪一个断点,1,2,3,4......)

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

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

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

比如:(Pdb) p 1+2

这里会打印出 3

再比如:(Pdb) p c #这里用来查看某个变量c的值

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断点无效

注意:

1:直接输入Enter,会执行上一条命令;

2:输入PDB不认识的命令,PDB会把他当做Python语句在当前环境下执行;

3:常用的命令有,(6)(8)(9)(10)(11)(12)(13)(14)(15)(16)(17)(18)(19)(20)

02

使用set_trace()设置断点

pdb单步执行太麻烦了,所以第二种方法是import pdb 之后,直接在代码里需要调试的地方放一个pdb.set_trace(),就可以设置一个断点, 程序会在pdb.set_trace()暂停并进入pdb调试环境,可以用pdb 变量名查看变量,或者c继续运行。

如下代码:

import pdb #导入这个模块

print('这是一个python调试程序')

def func1():

for i in range(5):

print(i)

def func2(a,b):

return a/b

if __name__=='__main__':

func1()

pdb.set_trace() #设置断点,程序会在调试的时候直接进入到这里暂停

result=func2(3,0)

print(result)

下面开始调试,

(base) C:Userslenovo>python F:Python调试.py #执行脚本

这是一个python调试程序

0

1

2

3

4 #自动执行到断点处

> f:研究生二年级下c#再学习python调试python调试python调试.py(14)()

-> result=func2(3,0)

(Pdb) n

ZeroDivisionError: division by zero

> f:研究生二年级下c#再学习python调试python调试python调试.py(14)()

-> result=func2(3,0)

(Pdb) n

--Return--

> f:研究生二年级下c#再学习python调试python调试python调试.py(14)()->None

-> result=func2(3,0)

(Pdb) n

总结:

使用set_trace()设置断点之后,调用脚本的时候,不再需要 -m pdb 这一块了,直接调用,然后就会进入调试模式,

几面会出现(Pdb),然后相关的执行命令和前面的是一样的。

03

pdb模块详解

1、pdb.set_trace() 设置断点

2、pdb.run(statement[, globals[, locals]]) ——主要用来调试代码块

statement:需要进行调试的某一段代码,以字符串的形式给出

globals: 设置statement运行的全局环境变量

locals: 设置statement运行的局部环境变量

整体的作用类似于python内置模块的eval函数。

s='''a=100

b=20

c=0

d=a/b

e=d/c

'''

pdb.run(s)

现在运行上面这段代码,python Python调试.py

的搭配下面的结果:

(base) C:Userslenovo>python F:研究生二年级下C#再学习Python调试Python调试Python调试.py

> (1)()

(Pdb) n

> (2)()

(Pdb) n

> (3)()

(Pdb) n

> (4)()

(Pdb) n

> (5)()

(Pdb) n

ZeroDivisionError: float division by zero

> (5)()

补充:

(1)globals:这个参数管控的是一个全局的命名空间,也就是我们在计算表达式的时候可以使用全局的命名空间中的函数,如果这个参数被提供了,并且没有提供自定义的__builtins__,那么会将当前环境中的__builtins__拷贝到自己提供的globals里,然后才会进行计算。关于__builtins__,它是python的内建模块,也就是python自带的模块,不需要我们import就可以使用的,例如我们平时使用的int、str、abs等都在这个模块中。关于它的说明可以参照这篇文章:点击打开链接。如果globals没有被提供,则使用python的全局命名空间。

(2)locals:这个参数管控的是一个局部的命名空间,和globals类似,不过当它和globals中有重复的部分时,locals里的定义会覆盖掉globals中的,也就是当globals和locals中有冲突的部分时,locals说了算,它有决定权,以它的为准。如果locals没有被 提供的话,则默认为globals。

3、pdb.runeval(expression,globals,locals)——主要用来调试表达式

expression也是以字符串的形式给出的,当表达式有返回值的时候,这个函数返回的值就是表达式所返回的值,如果没有返回值,那和上面的pdb.run()是一样的。

4、pdb.runcall(function[, argument, ...])——主要用来调试函数

对一个函数进行调试,注意,这里的function是一个函数或者是方法对象,不再是字符串哦,后面的是参数。当韩树有返回值的时候,函数的返回值就是runcall的返回值。

def myfunc(a,b,c):

return (a/b)/c

result=pdb.runcall(myfunc,100,20,5)

print(result)

5、pdb的其他一些方法

除了上面几个常用的常用方法以外,还有以下几个常用方法,

pdb.post_mortem([traceback])

pdb.pm()

Python学习路线和PDF电子书相互配合学习:获取方式很简单:只需关注转发文章然后私信小编(学习)就行!

Python 全系列

第一阶段:Python入门第二阶段:Python 深入与提高第三阶段:Python 网络与并发编程第四阶段:数据库编程基础第五阶段:Linux 环境编程基础第六阶段:Python 核心特性第七阶段:网页编程基础第八阶段:Python_Django 框架第九阶段:Python_Tornado 框架第十阶段:Python_大型电商项目第十一阶段:Python 爬虫开发第十二阶段:面试和成功求职的秘技第十三阶段:入职后快速成长到CTO

python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)_第1张图片
python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)_第2张图片
python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)_第3张图片
python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)_第4张图片
python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF)_第5张图片

获取方式很简单:只需关注转发文章然后添加微信:15803464551

备注:A   就可获取到了!

你可能感兴趣的:(python高级调试技巧(一)原生态的pdb调试(内含学习路线和PDF))