C/C++ 语言拥有调试工具gdb,同样对于高级语言Python,也有自己的调试利器pdb。
下面简单结合例子介绍pdb
有如下的python文件:example.py
#!/usr/bin/python
#-*- coding:utf-8 -*-
import json
def main():
with open("/root/test/1.json") as f:
content = f.read()
print "type(content):%s, content:%s" % (type(content), content)
print type(json.loads(content))
print json.loads(content)
if __name__ == "__main__":
a = 1
b = 2
c = 3
d = 4
main()
e = 5
如果想要进行调试,pdb提供了两种手段:
(1)执行 python -m pdb example.py从代码入口处进入调试
[root@hzclov51 test]# cp file_operate.py example.py
[root@hzclov51 test]# python -m pdb example.py
> /root/test/example.py(4)<module>()
-> import json
(Pdb) q
(2)在需要调试的代码处添加如下语句设置断点:
import pdb
pdb.set_trace()
然后执行 python example.py 将直接运行代码至断点处
#!/usr/bin/python
#-*- coding:utf-8 -*-
import json
def main():
with open("/root/test/1.json") as f:
content = f.read()
print "type(content):%s, content:%s" % (type(content), content)
print type(json.loads(content))
print json.loads(content)
if __name__ == "__main__":
a = 1
b = 2
import pdb
pdb.set_trace()
c = 3
d = 4
main()
e = 5
[root@hzclov51 test]# python example.py
> /root/test/example.py(17)<module>()
-> c = 3
(Pdb)
一般,第二种方法为推荐用法。
pdb的常用命令和gdb基本相同
help(h) | 帮助 |
break(b) | 设置断点(指定行或者函数设置) |
next(n) | 往下执行一行(如果是函数不进入函数内部) |
continue(c) | 继续执行直到下一个断点处 |
step(s) | 单步调试(一句句执行,遇到函数进入函数内部执行) |
return(r) | 返回函数调用处 |
list(l) | 列出代码(标识出当前停止的代码处) |
print(p) | 打印变量 |
exit(q) | 退出pdb |
[root@hzclov51 test]# python example.py
> /root/test/example.py(17)<module>()
-> c = 3
(Pdb) h
Documented commands (type help <topic>):
========================================
EOF bt cont enable jump pp run unt
a c continue exit l q s until
alias cl d h list quit step up
args clear debug help n r tbreak w
b commands disable ignore next restart u whatis
break condition down j p return unalias where
Miscellaneous help topics:
==========================
exec pdb
Undocumented commands:
======================
retval rv
(Pdb) h b
b(reak) ([file:]lineno | function) [, condition]
With a line number argument, set a break there in the current
file. With a function name, set a break at first executable line
of that function. Without argument, list all breaks. If a second
argument is present, it is a string specifying an expression
which must evaluate to true before the breakpoint is honored.
The line number may be prefixed with a filename and a colon,
to specify a breakpoint in another file (probably one that
hasn't been loaded yet). The file is searched for on sys.path;
the .py suffix may be omitted.
(Pdb) h l
l(ist) [first [,last]]
List source code for the current file.
Without arguments, list 11 lines around the current line
or continue the previous listing.
With one argument, list 11 lines starting at that line.
With two arguments, list the given range;
if the second argument is less than the first, it is a count.
(Pdb) b 3
*** Blank or comment
(Pdb) b 5
Breakpoint 1 at /root/test/example.py:5
(Pdb) n
> /root/test/example.py(18)<module>()
-> d = 4
(Pdb) n
> /root/test/example.py(19)<module>()
-> main()
(Pdb) s
--Call--
> /root/test/example.py(5)main()
-> def main():
(Pdb) n
> /root/test/example.py(6)main()
-> with open("/root/test/1.json") as f:
(Pdb) n
> /root/test/example.py(7)main()
-> content = f.read()
(Pdb) n
> /root/test/example.py(8)main()
-> print "type(content):%s, content:%s" % (type(content), content)
(Pdb) p content
'{"a":"a1","b":{"b1":"b11"}}\n'
(Pdb) r
type(content):<type 'str'>, content:{"a":"a1","b":{"b1":"b11"}}
<type 'dict'>
{u'a': u'a1', u'b': {u'b1': u'b11'}}
--Return--
> /root/test/example.py(10)main()->None
-> print json.loads(content)
(Pdb) r
> /root/test/example.py(20)<module>()
-> e = 5
(Pdb) l
15 import pdb
16 pdb.set_trace()
17 c = 3
18 d = 4
19 main()
20 -> e = 5
21
[EOF]
(Pdb) p a,b,c,d,e
*** NameError: NameError("name 'e' is not defined",)
(Pdb) p a,b,c,d
(1, 2, 3, 4)
(Pdb) n
--Return--
> /root/test/example.py(20)<module>()->None
-> e = 5
(Pdb) n
[root@hzclov51 test]#