使用pdb模块调试Python程序实例


Posted in Python onJune 02, 2015

在Python中,语法错误可以被Python解释器发现,但逻辑上错误或变量使用错误却不容易发现,如果结果没有符合预期,则需要调试,一个很好的调试工具:Python自带的pdb模块。pdb是Python自带的调试模块。使用pdb模块可以为脚本设置断点、单步执行、查看变量值等。

pdb可以用命令行参数的方式启动,也可以使用import 将其导入后再使用。

>>> dir(pdb)  

['Pdb', 'Repr', 'Restart', 'TESTCMD',.....,'re', 'run', 'runcall', 'runctx', 'runeval', 'set_trace', 'sys', 'test', 'traceback'] 

常见的pdb函数有以下几个:

【pdb.run()函数】

>>> 该函数主要用于调试语句块
>>> 基本用法如下

>>> help(pdb.run)  

Help on function run in module pdb:  

  

run(statement, globals=None, locals=None)  

>>>参数含义

statement: 要调试的语句块,以字符串的形式表示
globals:   可选参数,设置statement运行的全局环境变量
locals:     可选参数,设置statement运行的局部环境变量
>>>简单示例

>>> import pdb                # 导入调试模块  

>>> pdb.run('''''               # 调用run()函数执行一个for循环 

for i in range(3): 

    i *= 3 

    print(i) 

    ''')  

> <string>(2)<module>()       

(Pdb) n                       # (Pdb)为调试命令提示符,表示可输入调试命令  

> <string>(3)<module>()  

(Pdb) n                       # n(next)表示执行下一行  

> <string>(4)<module>()  

(Pdb) print(i)                # 打印变量i的值  

0  

(Pdb) continue                # 继续运行程序  

0  

3  

6 

【pdb.runeval()函数】
>>>该函数主要用于调试表达式
>>>基本用法如下

>>> help(pdb.runeval)  

Help on function runeval in module pdb:  

  

runeval(expression, globals=None, locals=None) 

>>> 参数含义

expression: 要调试的,
globals:   可选参数,设置statement运行的全局环境变量
locals:     可选参数,设置statement运行的局部环境变量

>>> 简单示例

>>> import pdb                  # 导入pdb模块  

>>> lst = [1, 2, 3]             # 定义一个列表  

>>> pdb.runeval('lst[1]')       # 调用runaval()函数来调试表达式lst[1]  

> <string>(1)<module>()  

(Pdb) n                         # 进入调试状态,使用n命令,单步执行  

--Return--  

> <string>(1)<module>()->2  

(Pdb) n                         # 单步执行  

2                               # 返回表达式的值  

>>> pdb.runeval('3 + 5*6/2')    # 使用runaval()函数来调试表达式3+5*6/2  

> <string>(1)<module>()->2  

(Pdb) n  

--Return--  

> <string>(1)<module>()->18  

(Pdb) n                         # 使用n命令单步执行  

18                              # 最后得出表达式的值 

【pdb.runcall()函数】

>>>该函数主要用于调试函数
>>>基本用法如下

>>> help(pdb.runcall)  

Help on function runcall in module pdb:  

  

runcall(*args, **kwds) 

>>> 参数含义
function:          函数名
args(kwds):        函数的参数
>>> 简单示例

>>> import pdb                           # 导入模块  

>>> def sum(*args):                      # 定义函数sum,求所有参数之和  

    res = 0  

    for arg in args:  

        res += arg  

    return res  

  

>>> pdb.runcall(sum, 1, 2, 3, 4)         # 使用runcall调试函数sum  

> <pyshell#53>(2)sum()  

(Pdb) n                                  # 进入调试状态,单步执行  

> <pyshell#53>(3)sum()  

(Pdb) n                                  # 单步执行  

> <pyshell#53>(4)sum()         

(Pdb) print(res)                         # 使用print打印res的值  

0  

(Pdb) continue                           # 继续执行  

10  

>>> pdb.runcall(sum, 1, 2, 3, 4, 5, 6)   # 调用runcall调试函数sum,参数不同  

  

> <pyshell#53>(2)sum()                 

(Pdb) continue                           # 继续执行  

21                                       # 函数最后返回结果 

【pdb.set_trace()函数】

>>>该函数主要用于脚本中设置硬断点
>>>基本用法如下

>>> help(pdb.set_trace)  

Help on function set_trace in module pdb:  

  

set_trace() 

>>>简单示例

# file: test.py  

  

import pdb  

  

pdb.set_trace()  

for i in range(5):  

    i *= 5  

    print(i) 

运行脚本后显示:

> d:\learn\python\test.py(6)<module>()  

-> for i in range(5):  

(Pdb) list                     # 使用list列出脚本内容  

  1     # file: test.py  

  2       

  3     import pdb  

  4       

  5     pdb.set_trace()        # 使用set_trace()设置硬断点  

  6  ->  for i in range(5):  

  7         i *= 5  

  8         print(i)  

[EOF]                          # 列出脚本内容结束  

(Pdb) continue                 # 使用continue继续执行  

0  

5  

10  

15  

20 

【pdb调试命令】
pdb中的调试命令可以完成单步执行、打印变量值、设置断点等功能。pdb主要命令如下

------------------------------------------------------------------------------  

# 完整命令                    简写命令                      描述  

------------------------------------------------------------------------------  

# args                         a                            打印当前函数的参数  

# break                        b                            设置断点  

# clear                        cl                           清除断点  

# condition                    无                           设置条件断点  

# continue                     c                            继续运行,直到遇到断点或者脚本结束  

# disable                      无                           禁用断点  

# enable                       无                           启用断点  

# help                          h                           查看pdb帮助  

# ignore                       无                           忽略断点  

# jump                         j                            跳转到指定行数运行  

# list                         l                            列出脚本清单  

# next                         n                            执行下条语句,遇到函数不进入其内部  

# print                        p                            打印变量值  

# quit                         q                            退出pdb  

# return                       r                            一致运行到函数返回  

# tbreak                       无                           设置临时断点、断点只中断一次  

# step                         s                            执行下一条语句,遇到函数进入其内部  

# where                        w                            查看所在的位置  

# !                           无                           在pdb中执行语句                     

>>>简单示例
# -*- coding:gbk -*-  

# file: prime.py  

#  

import math  

# isprime函数判断一个整数是否为素数  

# 如果i能被2到i的平方根内的任意一个数整除,  

# 则i不是素数,返回0,否则i是素数,返回1。  

def isprime(i):  

    for t in range(2, int(math.sqrt(i)) + 1):  

        if i % t == 0:  

            return 0  

  

  

print('100~110之间素数有: ')  

for i in range(100, 110):  

    if isprime(i):  

        print(i) 

先运行下面命令:

d:\Learn\Python>python -m pdb prime.py 

后输入以下命令:

d:\Learn\Python>python -m pdb prime.py  

> d:\learn\python\prime.py(4)<module>()  

-> import math  

(Pdb) list                                           # 运行前面命令后停在这里,list默认只列出11行  

  1     # -*- coding:gbk -*-  

  2     # file: prime.py  

  3     #  

  4  -> import math  

  5     # isprime函数判断一个整数是否为素数  

  6     # 如果i能被2到i的平方根内的任意一个数整除,  

  7     # 则i不是素数,返回0,否则i是素数,返回1。  

  8     def isprime(i):  

  9         for t in range(2, int(math.sqrt(i)) + 1):  

 10             if i % t == 0:  

 11                 return 0  

(Pdb) l 14,17                                        # 使用list命令,列出14行,到17行  

 14     print('100~110之间素数有: ')  

 15     for i in range(100, 110):  

 16         if isprime(i):  

 17             print(i)  

(Pdb) b 14                                           # 使用break命令设置断点  

Breakpoint 1 at d:\learn\python\prime.py:14          # 返回断点编号: 1  

(Pdb) b isprime                                      # 在函数isprime设置断点  

Breakpoint 2 at d:\learn\python\prime.py:8           # 返回断点编号: 2  

(Pdb) c                                              # 使用c命令运行运行脚本  

> d:\learn\python\prime.py(14)<module>()             # 停在断点1处,即第14行  

-> print('100~110之间素数有: ')  

(Pdb) c                                              # 使用c命令继续运行脚本  

100~110之间素数有:                                   # 第14行脚本输出  

> d:\learn\python\prime.py(9)isprime()               # 停在断点2,即isprime函数处  

-> for t in range(2, int(math.sqrt(i)) + 1):  

(Pdb) b 15                                           # 在第15行处设置断点  

Breakpoint 3 at d:\learn\python\prime.py:15  

(Pdb) disable 2                                      # 禁用断点2,即isprime函数处的断点  

(Pdb) c                                              # 使用c命令继续运行脚本  

> d:\learn\python\prime.py(15)<module>()             # 停在断点3处,即第15行  

-> for i in range(100, 110):  

(Pdb) print(i)                                       # 使用print打印变量i的值  

100  

(Pdb) c                                              # 继续运行脚本  

> d:\learn\python\prime.py(15)<module>()  

-> for i in range(100, 110):  

(Pdb) p i                                            # 打印i的值  

101  

(Pdb) enable 2                                       # 恢复断点2,即isprime函数处的断点  

(Pdb) c                                              # 继续运行脚本  

> d:\learn\python\prime.py(9)isprime()                 

-> for t in range(2, int(math.sqrt(i)) + 1):  

(Pdb) n                                              # 单步执行下一条语句                                            

> d:\learn\python\prime.py(10)isprime()  

-> if i % t == 0:  

(Pdb) print(t)                                       # 使用print打印变量t的值  

2  

(Pdb) cl                                             # 清楚所有断点,输入y确认  

Clear all breaks? y  

(Pdb) c                                              # 继续运行脚本  

103  

105  

107  

109  

(Pdb) q                                              # 使用quit(q)退出pdb调试 
Python 相关文章推荐
Python中的MongoDB基本操作:连接、查询实例
Feb 13 Python
python实现域名系统(DNS)正向查询的方法
Apr 19 Python
python使用matplotlib绘制折线图教程
Feb 08 Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
May 30 Python
python实现寻找最长回文子序列的方法
Jun 02 Python
Sanic框架流式传输操作示例
Jul 18 Python
Python Pandas分组聚合的实现方法
Jul 02 Python
python 检查数据中是否有缺失值,删除缺失值的方式
Dec 02 Python
python实现简单飞行棋
Feb 06 Python
python的sys.path模块路径添加方式
Mar 09 Python
Python SMTP发送电子邮件的示例
Sep 23 Python
解决Python 写文件报错TypeError的问题
Oct 23 Python
python使用xmlrpclib模块实现对百度google的ping功能
Jun 02 #Python
python基于xmlrpc实现二进制文件传输的方法
Jun 02 #Python
Python中的自省(反射)详解
Jun 02 #Python
Python中pip安装非PyPI官网第三方库的方法
Jun 02 #Python
Python中字典创建、遍历、添加等实用操作技巧合集
Jun 02 #Python
python实现的文件同步服务器实例
Jun 02 #Python
Python中for循环控制语句用法实例
Jun 02 #Python
You might like
实现php加速的eAccelerator dll支持文件打包下载
2007/09/30 PHP
PHP三元运算的2种写法代码实例
2014/05/12 PHP
PHP编写的图片验证码类文件分享
2016/06/06 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
向大师们学习Javascript(视频与PPT)
2009/12/27 Javascript
JQuery从头学起第二讲
2010/07/04 Javascript
js history对象简单实现返回和前进
2013/10/30 Javascript
js插件方式打开pdf文件(浏览器pdf插件分享)
2013/12/20 Javascript
jQuery基础语法实例入门
2014/12/23 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
jQuery中extend()和fn.extend()方法详解
2015/06/03 Javascript
js print打印网页指定区域内容的简单实例
2016/11/01 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
2018/12/09 Javascript
了解JavaScript函数中的默认参数
2019/05/30 Javascript
小程序实现上下移动切换位置
2019/09/23 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
JavaScript对象访问器Getter及Setter原理解析
2020/12/08 Javascript
[00:03]DOTA2新版本PA至宝展示
2014/11/19 DOTA
[44:43]完美世界DOTA2联赛决赛日 FTD vs GXR 第一场 11.08
2020/11/11 DOTA
python进阶教程之词典、字典、dict
2014/08/29 Python
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
python解析xml文件操作实例
2014/10/05 Python
Python3处理文件中每个词的方法
2015/05/22 Python
Python中规范定义命名空间的一些建议
2016/06/04 Python
PyCharm使用教程之搭建Python开发环境
2016/06/07 Python
python基础教程之Filter使用方法
2017/01/17 Python
Django框架教程之正则表达式URL误区详解
2018/01/28 Python
django数据库自动重连的方法实例
2019/07/21 Python
Jupyter Notebook折叠输出的内容实例
2020/04/22 Python
Django:使用filter的pk进行多值查询操作
2020/07/15 Python
CSS3制作圆角图片和椭圆形图片
2016/07/08 HTML / CSS
清洁工个人总结
2015/03/04 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
幼儿园新学期开学寄语
2015/05/27 职场文书
2016消防宣传标语口号
2015/12/26 职场文书