使用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编程中对文件和存储器的读写示例
Jan 25 Python
python @property的用法及含义全面解析
Feb 01 Python
Python 爬取携程所有机票的实例代码
Jun 11 Python
一文带你了解Python中的字符串是什么
Nov 20 Python
Python中Numpy ndarray的使用详解
May 24 Python
pycharm 安装JPype的教程
Aug 08 Python
python os.fork() 循环输出方法
Aug 08 Python
Python Django 封装分页成通用的模块详解
Aug 21 Python
python网络编程socket实现服务端、客户端操作详解
Mar 24 Python
使用 Python 读取电子表格中的数据实例详解
Apr 17 Python
pymysql模块使用简介与示例
Nov 17 Python
Anaconda的安装与虚拟环境建立
Nov 18 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开发者事半功倍的十大技巧小结
2010/04/20 PHP
解析WordPress中的post_class与get_post_class函数
2016/01/04 PHP
PHP错误处理函数
2016/04/03 PHP
thinkphp分页集成实例
2017/07/24 PHP
利用jQuery的$.event.fix函数统一浏览器event事件处理
2009/12/21 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
2014/06/27 Javascript
最精简的JavaScript实现鼠标拖动效果的方法
2015/05/11 Javascript
JQuery中DOM加载与事件执行实例分析
2015/06/13 Javascript
JavaScript创建对象的方式小结(4种方式)
2015/12/17 Javascript
iframe中使用jquery进行查找的方法【案例分析】
2016/06/17 Javascript
[js高手之路]寄生组合式继承的优势详解
2017/08/28 Javascript
vue轮播图插件vue-awesome-swiper
2017/11/27 Javascript
vue组件中使用iframe元素的示例代码
2017/12/13 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
利用CDN加速react webpack打包后的文件详解
2018/02/22 Javascript
详解JavaScript添加给定的标签选项
2018/09/17 Javascript
js中int和string数据类型互相转化实例
2019/01/16 Javascript
vue图片上传组件使用详解
2019/12/23 Javascript
Electron实现应用打包、自动升级过程解析
2020/07/07 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
2020/08/30 Javascript
python爬虫框架talonspider简单介绍
2017/06/09 Python
Python探索之自定义实现线程池
2017/10/27 Python
基于Python Numpy的数组array和矩阵matrix详解
2018/04/04 Python
分析经典Python开发工程师面试题
2019/04/08 Python
int在python中的含义以及用法
2019/06/27 Python
python简单区块链模拟详解
2019/07/03 Python
解决Django中多条件查询的问题
2019/07/18 Python
创先争优制度
2014/01/21 职场文书
金融事务专业求职信
2014/04/25 职场文书
企业宗旨标语
2014/06/10 职场文书
公司离职证明范本(5篇)
2014/09/17 职场文书
第二批党的群众路线教育实践活动总结报告
2014/10/30 职场文书
Redis安装启动及常见数据类型
2021/04/14 Redis
MySQL为id选择合适的数据类型
2021/06/07 MySQL
MySQL 外连接语法之 OUTER JOIN
2022/04/09 MySQL
安装Ruby和 Rails的详细步骤
2022/04/19 Ruby