我喜欢Python,我喜欢Spyder,但我发现Spyder的调试非常糟糕!
你有解决方案,或者你能告诉我你如何调试python脚本和函数吗?
我在Windows 8.1 64位上使用全新安装的Anaconda。
答案 0 :(得分:43)
( Spyder dev here )我们知道Spyder的调试体验远非理想。我们现在提供的内容与标准的Python调试器非常相似,但是我们正在努力改进下一个主要版本的内容,以提供更接近科学家对调试器的期望(简而言之,一个常规的IPython控制台)您在当前断点处检查并绘制变量。)
现在谈谈你的观点:
这是真的。我们正在考虑改进这一点,以便如果用户按下Run按钮,并且当前文件中存在断点,则Spyder进入调试模式并执行程序直到满足第一个断点。
< / LI> ipdb
是IPython调试器控制台。不幸的是,由于IPython架构的限制,它非常有限(没有代码完成,也没有用箭头浏览历史记录)。此外,无法在ipdb
或常规pdb
控制台中运行任意Python代码。您可以在ipdb
中运行的命令是在评估其中的help
命令时可以阅读的命令。
那是因为,正如我所说,你无法评估任意Python代码。
您需要在我们的编辑器中添加新的断点,以便它们与我们的Python / IPython控制台同步
答案 1 :(得分:20)
您必须明白,事实上您正在使用Python debugger pdb
和ipdb
的不同集成(使用pdb
并且可以使用模块ipdb
访问) 。我希望这个简单的例子可以帮助你更好地使用它。
假设您要调试此代码:
def Waiting_fun(): #1 line number one
for i in range(100): #2
pass #3
#4
def New_sum(lista, to_s = False): #5
result = 0 #6
print 1 #7
for i in lista: #8
print "summed" #9
result +=i #10
Waiting_fun() #11
if to_s: #12
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
%debug
我做的第一件事是使用magic命令%debug
从iPython调用pdb,你可以使用%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
。您可以在official docs中找到所有命令,也可以使用命令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 # we go to the breakpoint
(Pdb) s # we step into the function
(Pdb) args # we see what parameters are inserted
(Pdb) s # going step-by-step
(Pdb) ⏎ # series of Enters go line by line quicker
#Here I'll use whatis command but in fact I just look to
# the type in variable explorer of spyder.
(Pdb) whatis result #check if result is still int
(Pdb) unt #or until -useful to exiting from loops see doc.
(Pdb) n # we don't enter to the Waiting_fun function
(Pdb) s # going step-by-step
(Pdb) whatis result #we find that there the int is converted
(Pdb) j 6 # for double checking we jump back to 6 were the result is assigned
# We may be tempted to j(ump) to line 12 but doing so we would skip all the code
#for avoiding a series of `s`,`unt` and `n` we can use this solution:
(Pdb) tbreak 12 #set a new temporary breakpoint. Also `b` it's ok most of the time
(Pdb) c # go to it
(Pdb) j 6 # we jump to 6 the code we jump is NOT executed
(Pdb) whatis result# we find that if we jump 12-13 result is still int
现在我们找到了错误。我们还可以测试解决方案我们重复这一步骤直到12,我们设置to_s = False
(Pdb) to_s = False #!to_s = False to be on the safe side
有效。在 Python控制台中使用标准pdb的一个重要特性是,您有自动竞争,您可以使用变量资源管理器,而不是使用whatis
和pp
:
使用变量资源管理器,您还可以更改变量的值,使事情变得更快。
找到错误的另一个更聪明的方法是使用条件断点( Shift + F12 )Spyder的一大优势是调试并使用列表断点。当条件为True
时,条件断点被激活在我们的例子中,我们想要找到b变为字符串的位置,因此条件为:type(b) == str
。我通常会放置很多条件断点,看看哪个符合条件。为此,请不要使用 Shift + F12 ,但要在该行旁边双击普通断点,然后转到Debug-&gt;列出断点并复制并过去表中的条件到每个断点,如下图所示。
从这里开始使用的命令是:
(Pdb) c # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint
答案 2 :(得分:4)
pdb调试器与常规python 一起正常工作。所以在Spyder中,只要我想交互式调试,我就切换到python控制台。
import pdb
def yourfunction():
# Interesting stuff done here
pdb.set_trace()
使用pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/
进行调试的简介答案 3 :(得分:1)
以下是我在Spyder中调试的方法,以避免冻结IDE。如果我在调试模式下更改脚本,我会这样做。
还有点烦人,但它还有清除(重置)变量列表的额外好处。
答案 4 :(得分:0)
关于第3点的一点额外费用:
在我看来,调试控制台经常冻结,进行打印,评估等,但按下停止(退出调试)按钮通常会将其恢复到调用堆栈的底部,然后我可以重新启动('你正在调试的框架。值得一试。这可能适用于更高版本的Spyder(2.3.5.2)
答案 5 :(得分:0)
您可以使用调试快捷键,例如: 跳过F10 进入F11 在工具&gt;首选项&gt;键盘快捷键
答案 6 :(得分:0)