文章目录(Table of Contents)
简介
这一篇文章主要介绍一些 Python 的两个调试方法,使用 pdb(或是 ipdb)和 logging 这两种方式进行调试。关于 logging 模块更加详细的使用,可以参考链接,Python 的 logging 模块的使用。
关于 pdb 的内容,部分参考自以下的链接,【python】来学学debugger吧,不能只会用print调试呀!
logging
之前自己调试的时候其实经常会使用 print 来进行调试,但是最后使用的时候会打印很多信息。通常情况下,当调试完毕之后就不想打印这么多了,这个时候可以使用 logging 来进行调试。
关于详细资料可以查看这个链接(这里有非常详细的使用方式) : Python 的 logging 模块的使用
下面大致看一下如何使用 logging 模块。使用 logging 需要在最开始添加一行配置,如下所示:
- import logging
- logging.basicConfig(level=logging.INFO)
logging 允许你指定记录信息的级别,有debug
,info
,warning
,error
等几个级别。当我们指定level=INFO
时,logging.debug
就不起作用了。同理,指定level=WARNING
后,debug
和info
就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
logging
的另一个好处是通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件。(来自廖雪峰Python3-调试)
我们看一个例子,来大致了解一下:
- import fire
- import pdb
- import logging
- logging.basicConfig(level=logging.INFO)
- def Multiplication(x, y):
- """
- x*y
- """
- logging.info("To Calcuate %d * %d" % (x,y))
- logging.info("--- --- ---")
- z=x*y
- #pdb.set_trace()
- return(z)
- def main():
- fire.Fire(Multiplication)
- if __name__ == '__main__':
- main()
我们看一下运行的效果,这样调试信息会直接输出出来;
我们也可以将logging输出到文件中,只需要修改第一行的配置;
- logging.basicConfig(filename='logger.log',level=logging.INFO)
使用 pdb 进行调试
设置断点
pdb 是 python 自带的一种调试方式。这种方法可以设置断点,进行单步调试,查看栈内变量。使用 pdb 最简单的方式就是在代码中加入 breakpoint()
即可。然后代码就会停在指定的位置。(或是使用 pdb.set_trace
也是可以的)
有的时候我们无法直接对原始文件进行修改,也可以使用命令行的方式启动调试:
- python -m pdb xxx.py
运行上面的代码之后,他会在第一个可以停下来的地方就停下来。
pdb 监视当前程序状态
我们可以使用 pdb 很方便的检视当前程序的状态,下面是一些常用的命令:
w
:查看代码的堆栈调用(这里 > 表示我们当前在什么 frame);u
:使用 u 或是 up 跳转到上一个 frame;d
:使用 d 或是 down 跳转到下一个 frame;l
:查看当前断点附近的代码;ll
:显示当前函数的全部代码;
下图中我们展示了当前所在的堆栈,可以看到:
- 第一次使用 w 查看的时候在 read_config 函数里面;
- 之后可以 u 返回上面一层 frame;
- 最后再次使用 w 查看的时候可以看到返回了调用 read_config 处的代码;
pdb 控制程序运行
上面我们使用 breakpoint()
让程序停在了想要的位置,同时查看了程序的信息。接着我们可以使用 pdb 来控制程序的运行。下面展示一些常用的操作:
下面是一些常用的控制程序运行的代码。
- (Pdb)n #单步运行
- (Pdb)s #细点运行,进入到某个函数里面,也就是 step
- (Pdb)c #跳到下个断点
总结一下,我们可以分别使用:
n
:单步调试程序,但是遇到函数会直接运行结束;s
:与上面 n 不同的是,在遇到函数时候,会进入函数内部运行;until
:运行直到行数比现在的行数大为止(可以用于跳出循环或函数);until xx
:这个命令可以带有参数,until 10
就是表示运行到第 10 行(不能在不同函数之间跳转);
r
:使用r
或是return
停在函数 return 之前;c
:使用c
或是continue
来继续程序直到结束;b
:设置断点,和breakpoint
等价,例如b 5
就是表示在当前文件的第五行设置断点;b
后面什么都不加,就是列出所有的断点;b function_name
可以停在指定的函数里面(我们需要确保此时这个函数已经被 import 进来了,可以使用b 行数
,直接跳转到 import 之后,然后在函数里面打断点);b 文件路径/文件名:行数
,可以在指定文件的指定行数进行断点,例如b ../utils/readConfig.py:7
表示在文件的第七行设置断点,这里的路径是与当前文件相对的路径;
-
clear
:用于删除断点,clear id
删除指定的断点;
pdb 命令合集
下面是我在网上找到的一个 pdb 的命令合集。少了使用 w
查看当前堆栈,使用 u
和 d
对堆栈进行改变。使用 until
运行到某行。
使用 ipdb 进行调试
ipdb 可以看作是上面 pdb 的升级版,需要进行安装。使用pip install ipdb
即可轻松安装。在使用的时候,有两种方式,分别是「集成到源代码中」和「命令式」,我们分别来看例子。
ipdb 使用方式--集成到源代码中
我们可以在代码指定的位置插入断点,从而进行调试。下面我们看一个例子。
- def add_x_y(x, y):
- import ipdb; ipdb.set_trace() # 打断点
- return x+y
- if __name__ == "__main__":
- x1 = 1
- y1 = 2
- result = add_x_y(x1, y1)
我们运行这个代码,程序会在进入函数 add_x_y
后停止,展开 Ipython
环境,就可以自由地调试了。例如我们可以通过 a
查看输入函数的所有参数:
ipdb 使用方式--命令式
除了上面的方式外,我们还可以使用以下的命令按步执行,边运行边跟踪代码进行调试。下面的方法可以启动 ipdb 的调试环境:
- python -m ipdb your_code.py
首先我们通过上面的命令进入 ipdb 的调试环境:
接着我们可以通过一些常见的命令进行调试。下面是一些常见的命令:
h
,调出 ipdb 的帮助文档;b
,打断点,使用b line_number(break)
的方式给指定的行号位置加上断点。使用b file_name:line_number
的方法给指定的文件(还没执行到的代码可能在外部文件中)中指定行号位置打上断点;n(next)
,执行下一个语句(不会进入函数内部);s(step into)
,进入函数内部进行调试;c(continue)
,执行代码,直到遇到下一个断点;w(where)
,查看自己在哪里;q
,退出调试;
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论