pdb的使用

现在的IDE很方便了,调试什么的算是基础的功能,但是有时候在服务器上的时候是没有那么方便的,所有掌握pdb 或者 python 3.7 中提供的 breakpoint 是非常有必要的。下面文章只是写了一些简单的用法,pdb 还有一些文章中没有提到的功能,但若想简单实用,且入门的话,这就足够了。

开始

插入代码,开启调试

1
import pdb; pdb.set_trace()

python 3.7 中提供了 breakpoint() ,breakpoint() 和 pdb 一样导入 pdb 并调用 pdb.set_trace()。我们还可以在环境变量中使用 PYTHONBREAKPOINT 来确认是否启用 breakpoint, PYTHONBREAKPOINT=0 将完全禁用 breakpoint()

我们也可以不用修改代码来设置,可以使用 -m 参数,例如:python -m pdb app.py 参数1 参数2。参数1,参数2 是 app.py 所需的,如果不需要则不需要传入。

常用命令:

查看源代码

1
2
3
4
5
6
7
(Pdb) ll
4 def get_path(filename):
5 """Return file's path or empty string if no path."""
6 head, tail = os.path.split(filename)
7 import pdb; pdb.set_trace()
8 -> return head
(Pdb)

l 是查看当前调试位置的11行

p 查看变量

1
2
3
4
(Pdb) p head 
'/Users/rex/Desktop/flask/py-summer/test_project'
(Pdb) p tail
'server.py'

pp 使得结果更易读

单步调试 s 和 n

区别:n (相当于 step over )不进入函数,s ( 相当于 step into) 进入,我们可以二者结合使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(Pdb) ll # 查看当前代码
1 from application.router import *
2 import os
3
4
5 def get_path(filename):
6 """Return file's path or empty string if no path."""
7 head, tail = os.path.split(filename)
8 return head
9
10 filename = __file__
11 import pdb; pdb.set_trace()
12 -> filename_path = get_path(filename) # 调试位置
13 print(f'path = {filename_path}')
14
15 if __name__ == '__main__':
16 app.run("127.0.0.1", "8080", use_reloader=False)
(Pdb) s # --Call-- 进入了 get_path 函数
--Call--
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(5)get_path()
-> def get_path(filename):
(Pdb) ll # 查看调试位置
5 -> def get_path(filename):
6 """Return file's path or empty string if no path."""
7 head, tail = os.path.split(filename)
8 return head
(Pdb) n # 下一步,不进入 os.path 中,如果这里使用 s 则进去了
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(7)get_path()
-> head, tail = os.path.split(filename)
(Pdb) n # 在下一步
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(8)get_path()
-> return head
(Pdb) ll # 查看调试的位置
5 def get_path(filename):
6 """Return file's path or empty string if no path."""
7 head, tail = os.path.split(filename)
8 -> return head
(Pdb) p head # 查看运行的 head 的值
'/Users/rex/Desktop/flask/py-summer/test_project'
(Pdb) n # --Return-- 代表函数结束,-> 之后的为返回值
--Return--
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(8)get_path()->'/Users/rex/D.../test_project'
-> return head
(Pdb) n # 下一步,调试位置下移
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(13)<module>()
-> print(f'path = {filename_path}')
(Pdb) ll
1 from application.router import *
2 import os
3
4
5 def get_path(filename):
6 """Return file's path or empty string if no path."""
7 head, tail = os.path.split(filename)
8 return head
9
10 filename = __file__
11 import pdb; pdb.set_trace()
12 filename_path = get_path(filename)
13 -> print(f'path = {filename_path}')
14
15 if __name__ == '__main__':
16 app.run("127.0.0.1", "8080", use_reloader=False)
(Pdb)

设置断点

方式1:b 文件: 行数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(Pdb) ll  # 查看当前调试的位置
1 from application.router import *
2 import os
3
4 def get_path(filename):
5 """Return file's path or empty string if no path."""
6 head, tail = os.path.split(filename)
7 return head
8
9 import pdb; pdb.set_trace()
10 -> filename = __file__
11 filename_path = get_path(filename)
12 print(f'path = {filename_path}')
13
14 if __name__ == '__main__':
15 app.run("127.0.0.1", "8080", use_reloader=False)
(Pdb) b server:6 # 在server.py 的文件中的第6行设置断点
Breakpoint 1 at /Users/rex/Desktop/flask/py-summer/test_project/server.py:6
(Pdb) c # 跳转到下一个断点
> /Users/rex/Desktop/flask/py-summer/test_project/server.py(6)get_path()
-> head, tail = os.path.split(filename)
(Pdb) ll # 查看断点的位置
4 def get_path(filename):
5 """Return file's path or empty string if no path."""
6 B-> head, tail = os.path.split(filename)
7 return head
(Pdb)

方式2: b 函数名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(Pdb) ll  # 查看代码
1 from application.router import *
2 import os
3
4 def get_path(filename):
5 """Return file's path or empty string if no path."""
6 head, tail = os.path.split(filename)
7 return head
8
9 import pdb; pdb.set_trace()
10 -> filename = __file__
11 filename_path = get_path(filename)
12 print(f'path = {filename_path}')
13
14 if __name__ == '__main__':
15 app.run("127.0.0.1", "8080", use_reloader=False)
(Pdb) b get_path # 在get_path函数的地方设置一个断点
Breakpoint 1 at /Users/rex/Desktop/flask/py-summer/test_project/server.py:4
(Pdb) b # 查看现在已有的断点
Num Type Disp Enb Where
1 breakpoint keep yes at /Users/rex/Desktop/flask/py-summer/test_project/server.py:4
(Pdb)

启用和禁用断点

使用命令 disable bpnumber 和 enable bpnumber 来禁用和重新启用断点。 bpnumber 是断点列表第一列 Num 中的断点编号

q 退出

更多信息

https://pythonfun.top/python-debugging-with-pdb-trp/