调试工作流程
您必须了解,实际上您正在使用Python调试器pdb
和的 不同集成ipdb
(和使用pdb
,并且可以使用模块访问ipdb
)。我希望这个简单的例子可以帮助您更好地使用它。
假设您要调试以下代码:
def Waiting_fun():
for i in range(100):
pass
def New_sum(lista, to_s = False):
result = 0
print 1
for i in lista:
print "summed"
result +=i
Waiting_fun()
if to_s:
result = str(result)
return result
a = New_sum([1,4,5,7,8])
b = New_sum([1,4],1)
c = 456
d = New_sum([6,8,9],1)
final_result = a*b*c*d
Out: Type error
使用iPython%debug快速进行首次调试
%debug
我要做的第一件事是使用magic命令从iPython调用pdb %debug
,您可以使用将它设置为默认机制%pdb
。
%debug
> /home/opdate/Desktop/test.py(23)<module>()
19 a = New_sum([1,4,5,7,8])
20 b = New_sum([1,4],1)
21 c = 456
22 d = New_sum([6,8,9],1)
---> 23 final_result = a*b*c*d
午餐后pdb
。您可以在官方文档中找到所有命令,也可以使用该命令h
显示它们。在此阶段,我唯一使用的命令是:
p
:打印您指定的变量
pp
:漂亮的版画
args
:如果您在函数内部,它将打印参数
pp locals()
:可以打印所有变量,但大多数情况下是一团糟!
!
如果您想避免与中列出的命令冲突,请使用它 h
whatis
variable_name:等价于类型(variable_name)
u
:将当前帧在堆栈跟踪中上移一层(移至较旧的帧)。
d
:将当前帧在堆栈跟踪中向下移动一级(到新的帧)。
q
:完成后,您可以使用q退出
在我们的情况下:
ipdb> pp a,b,c,d
(25, '5', 456, '23')
或ipdb> !a,b,c,d
(星号与第一个值之间没有空格)。很明显,b和d是字符串,以防我们可以使用:
ipdb> whatis b
<type 'str'>
使用断点更深入
70%的时间%debug
指向您解决方案。当您需要断点之类的更多功能时,就可以使用Spyder。在这种情况下,我们想了解为什么b
在字符串旁边放置一个断点(在编辑器窗口中双击行号旁边)。我发现使用标准Python控制台而不是IPython控制台进行调试要好得多,因此在开始调试之前请选择控制台:
然后打开 variable explorer
是否有任何变量将其删除。我使用Ctrl+F5开始调试,您可以使用顶部的按钮,但我更喜欢使用如下所示的快捷方式:
(Pdb) c
(Pdb) s
(Pdb) args
(Pdb) s
(Pdb) ⏎
(Pdb) whatis result
(Pdb) unt
(Pdb) n
(Pdb) s
(Pdb) whatis result
(Pdb) j 6
(Pdb) tbreak 12
(Pdb) c
(Pdb) j 6
(Pdb) whatis result
现在我们已经找到了错误。我们还可以测试一个解决方案,将步骤重复到12,然后设置to_s = False
(Pdb) to_s = False
有用。在Python控制台中使用标准pdb的一项重要功能是具有自动竞争功能,可以使用变量资源管理器而不是使用whatis
and pp
:
使用变量浏览器,您还可以更改变量的值,从而使事情变得更快。
条件断点
定位错误的另一种更聪明的方法是使用条件断点(Shift+ F12),Spyder的一大优势是可以调试和使用列表断点。当条件为时,条件断点被激活True
在我们的例子中,我们想定位b成为字符串的位置,因此条件为:type(b) == str
。我通常会放置很多条件断点,并查看哪些条件断点。为此,请不要使用Shift+,F12而是将正常断点双击该行旁边,然后转到Debug-> List断点,然后将表中的条件复制并粘贴到每个断点,如下图所示。
从这里使用的命令是:
(Pdb) c
(Pdb) u
(Pdb) d
sys.exit()
临时输入,但是如果有断点选项,会更方便。