【转载】PDB命令行调试Python代码
转载自这里。
(博主按:PDB调试python代码和用GDB调试c++代码很类似)
你有多少次陷入不得不更改别人代码的境地?如果你是一个开发团队的一员,那么你遇到上述境地的次数比你想要的还要多。然而,Python中有一个整洁的调试特性(像其他大多数语言一样),在这种情况下使用非常方便。本文是一篇快速教程,希望它能让你的编码生活更加容易。
1. 一个混乱的程序
出于本教程的目的,让我们研究一下下面的简单程序。
这个程序接收两个命令行参数,然后执行加法和减法操作。
(假设用户输入的是有效值,因此代码中我们没有进行错误处理。)
import sys
def add(num1=0, num2=0):
return int(num1) + int(num2)
def sub(num1=0, num2=0):
return int(num1) - int(num2)
def main():
#Assuming our inputs are valid numbers
print sys.argv
addition = add(sys.argv[1], sys.argv[2])
print addition
subtraction = sub(sys.argv[1], sys.argv[2])
print subtraction
if __name__ == '__main__':
main()
2. PDB
Python提供了一个有用的模块PDB,它实际上是一个交互式源代码调试器。
你需要下面的两行代码来使用此模块。
import pdb
pdb.set_trace()
看一下我们修改过的程序,里面包含了一些断点。
import pdb
import sys
def add(num1=0, num2=0):
return int(num1) + int(num2)
def sub(num1=0, num2=0):
return int(num1) - int(num2)
def main():
#Assuming our inputs are valid numbers
print sys.argv
pdb.set_trace() # <-- Break point added here
addition = add(sys.argv[1], sys.argv[2])
print addition
subtraction = sub(sys.argv[1], sys.argv[2])
print subtraction
if __name__ == '__main__':
main()
3. 程序执行触发调试器
一旦你设置好断点以后,你就可以像平时一样执行程序。
python debugger.py
程序将会在遇到的第一个断点处停止执行。
['debugger.py']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)
我们在第14行设置了一个断点,所以我们能看到将要执行的下一行是第15行。可以看到,在执行到第15行之前程序已经停止。
在这里我们有几个选项,让我们在下面步骤中看看一些调试指令。
4. 下一行->n
在你的调试器提示中,输入n运行到下一行。
> /Users/someuser/debugger.py(14)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) n
> /Users/someuser/debugger.py(15)main()
-> print addition
这会执行当前行代码,并准备执行下一行。
我们可以使用n来逐行执行整个程序,但这其实没有什么用处。
可能你已经看到,PDB实际上并没有进入我们的add函数中。下面,就让我们看看其他几个令调试更加有趣的选项。
注意:
一个更酷的特性是你可以单击回车键来执行以前的命令(在本例中只要指令n)。
5. 打印->p
下面,我们再次开始调试程序。(你可以通过单击c使PDB跳到末尾或者直到下一个断点,因为程序中我们并没有其他的断点了,所有程序将会执行完成。)
['debugger.py', '1', '2']
> /Users/someuser/debugger.py(14)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)
现在,如果我们想知道sys.argv中包含什么内容,我们可以输入以下内容:
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) p sys.argv
['debugger.py', '1', '2']
(Pdb) p sys.argv[1]
'1'
(Pdb)
使用这种方法可以相当方便地查看变量中实际存储着什么值。
现在我们将进入加法函数内部。
6. 单步->s
我们可以使用“s”进入加法函数内部。
(Pdb) s
--Call--
> /Users/someuser/debugger.py(4)add()
-> def add(num1=0, num2=0):
(Pdb) n
> /Users/someuser/debugger.py(5)add()
-> return int(num1) + int(num2)
(Pdb)
这将把我们带入加法函数的内部,现在我们可以在加法函数内部使用n、p和其他的操作指令。
此时单击“r”将会把我们带到前面进入函数的返回语句。
如果你想快速跳转到一个函数的结尾处,那么这个指令将很有用。
7. 动态添加断点- > b
前面,在程序运行之前,我们使用pdb.set_trace()设置了一个断点。
不过,经常在调试会话已经开始之后,我们想要在程序中特定的地方添加断点。
这里我们就可以使用选项“b”来实现这种目的。
我们重新开始执行程序。
['debugger.py', '', '']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb)
此时我在第18行设置一个断点。
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) b 18
Breakpoint 1 at /Users/someuser/debugger.py:18
(Pdb) c
We are in add--
3
> /Users/someuser/debugger.py(18)main()
-> print subtraction
(Pdb) p subtraction
-1
(Pdb)
从上面我们可以看到,PDB跳到了第18行并等待下一个指令。
同时,PDB还为该断点分配了一个号码(在本例中是1)。为了以后的执行,我们可以通过开启或禁用断点号码来启用或停用对应的断点。
8. 列表->l
有时在调试的时候,你可能会忘记此时你处在代码的什么地方。在这种情况下,使用“l”将会打印出一个友好的总结,它能够显示出此刻你在代码中的位置。
['debugger.py', '', '']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) l
10
11 def main():
12 #Assuming our inputs are valid numbers
13 print sys.argv
14 pdb.set_trace() # <-- Break point added here
15 -> addition = add(sys.argv[1], sys.argv[2])
16 print addition
17 subtraction = sub(sys.argv[1], sys.argv[2])
18 print subtraction
在调试会话期间,你可以分配变量来帮助你进行调试,知道这些对你来说也是有帮助的。例如:
['debugger.py', '', '']
> /Users/someuser/debugger.py(15)main()
-> addition = add(sys.argv[1], sys.argv[2])
(Pdb) n
We are in add--
> /Users/someuser/debugger.py(16)main()
-> print addition
(Pdb) p addition
3 #<--- addition here is 3
(Pdb) addition = 'this is now string' #<--- We changed the value of additon
(Pdb) n
this is now string #<--- Now when we print it we actually gets it as a string. that we just set above.
> /Users/someuser/debugger.py(17)main()
-> subtraction = sub(sys.argv[1], sys.argv[2])
注意:
如果你想设置一些如n(即PDB指令)这样的变量,你应该使用这种指令:
(Pdb) !n=5
(Pdb) p n
5
10. 结束->q
最后,在代码的任何地方如果你想结束调试,可以使用“q”,那么正在执行的程序将会终止。
11. 扩展阅读
本文只涉及到了PDB的表面用法,其实使用PDB你还可以做到更多(PDB 文档)。
使用IPython的人可以在ipdb中找到一个更好的调试器,它提供了tab补充、语法高亮和其他一些很酷的特性。
【转载】PDB命令行调试Python代码的更多相关文章
- shell脚本命令 运行python文件&python命令行运行python代码
单独的python文件运行的时候 报错: 在shell脚本中,运行shell脚本命令:在Python命令行中,运行Python代码.然而,“python hello.py”是一个脚本命令,不是pyth ...
- 设置PATH 环境变量、pyw格式、命令行运行python程序与多重剪贴板
pyw格式简介: 与py类似,我认为他们俩卫衣的不同就是前者运行时候不显示终端窗口,后者显示 命令行运行python程序: 在我学习python的过程中我通常使用IDLE来运行程序,这一步骤太过繁琐( ...
- 四则运算生成命令行程序 (Python)
Github项目地址:Github Pages 结对项目成员:张鹏 3118004985 郑靓 3118004988 一.项目需求分析 二.功能实现 三.代码实现or功能说明 ★ GUI功能扩展说明 ...
- [置顶] 如何在Python IDLE中调试Python代码?
好久没有用Python了,居然忘记了怎么在Python IDLE中调试Python代码.百度了一下,然后还是写下来吧,以免以后又忘记了. 1. Set break point in the sourc ...
- 在命令行输入python出现“Warning:This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see https://conda.
[现象] 在命令行输入python出现“Warning:This Python interpreter is in a conda environment, but the environment h ...
- 用不到 50 行的 Python 代码构建最小的区块链
引用 译者注:随着比特币的不断发展,它的底层技术区块链也逐步走进公众视野,引起大众注意.本文用不到50行的Python代码构建最小的数据区块链,简单介绍了区块链去中心化的结构与其实现原理. 尽管一些人 ...
- 在Linux命令行执行python命令
在Linux的命令行执行python的某些命令: [root@centos7 ~]# echo "import sys ;print(sys.path)"|python3.6 [' ...
- linux命令行调试邮件服务器
linux命令行调试邮件服务器 1. Linux客户端调试邮件过程 [root@mxtest ~]# telnet mail.xx.com 25 Trying 172.16.236.103... Co ...
- 命令行运行Python脚本时传入参数的三种方式
原文链接:命令行运行Python脚本时传入参数的三种方式(原文的几处错误在此已纠正) 如果在运行python脚本时需要传入一些参数,例如gpus与batch_size,可以使用如下三种方式. pyth ...
随机推荐
- YBT 2.4 AC自动机
其实这个专题NOIP几乎不考 AC自动机,就是能让题自动AC的东西,是不是十分神奇 对的,就是这么神奇 AC自动机是解决多模式串与文本串匹配的问题 是KMP+Trie树的结合,也是一个毒瘤算法 Key ...
- 微信小程序将view动态填满全屏
一.在app.js利用官方方法获取设备信息,将获取到的screenHeight.windowHeight度量单位统一由rpx换算为px 注:官方文档给出 [rpx换算px (屏幕宽度/750) ][ ...
- [sed]记录
sed的括号本身没有特殊意义,如果要保留通配内容,需要转义. echo "1) host" |sed 's/1) ([a-z])/$1) $1/' 有两处有问题. 1. 首先是上 ...
- iostat和iowait详细解说
简单的说,sar -u看出来的cpu利用率iowait 不实用,iostat -x 中的 svctm 和util 参数 命令形式: iostat -x 1 每隔一秒输出下 其中的svctm参数代表 ...
- 【updating】python读书笔记-The Django Book2.0(for django1.4)
原文:http://www.djangobook.com/en/2.0/frontmatter.html 译文:http://djangobook.py3k.cn/2.0/ 或者http://docs ...
- 解决SpringSecurity限制iframe引用页面的问题
使用Spring Security的过程中,需要使用iframe来引入其他域的页面,页面会报X-Frame-Options的错误,试了好几种方法一直未能很好的解决这个问题. 这里涉及到Spring S ...
- JAVA开发常用工具包
一个有经验的Java开发人员特征之一就是善于使用已有的轮子来造车.<Effective Java>的作者Joshua Bloch曾经说过:“建议使用现有的API来开发,而不是重复造轮子”. ...
- 【BZOJ1975】【SDOI2010】魔法猪学院 [A*搜索]
魔法猪学院 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description iPig在假期来到了传说中的魔法猪 ...
- 【BZOJ】1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
[算法]模拟 #include<cstdio> #include<algorithm> using namespace std; ,maxm=; int a[maxn],A[m ...
- JS练习题(左侧菜单下拉+好友选中)
题一.左侧菜单下拉 做题思路:先做菜单和子菜单,把子菜单默认隐藏.再用JS调样式. <style type="text/css"> *{ margin:0px auto ...