如何使用Python中的spyder高效调试?

时间:2015-02-02 14:48:09

标签: python debugging spyder

我喜欢Python,我喜欢Spyder,但我发现Spyder的调试非常糟糕!

  • 每次我提出一个断点,我需要按两个按钮:第一个 调试然后是继续按钮(它在第一行暂停 自动)这很烦人。
  • 此外,我没有自动完成的标准iPython控制台等,而是有一个糟糕的ipdb>>控制台,这只是垃圾。
  • 最糟糕的是,即使我写了打印件或简单的评估来试图弄清楚什么是bug,这个控制台也经常冻结。这比matlab差很多。
  • 最后但并非最不重要的,如果我从内部调用一个函数 IPDB>>控制台,并在其中放置一个断点,它不会停在那里。 看起来我必须在开始之前把断点放在那里 调试(ctrl + F5)。

你有解决方案,或者你能告诉我你如何调试python脚本和函数吗?

我在Windows 8.1 64位上使用全新安装的Anaconda。

7 个答案:

答案 0 :(得分:43)

Spyder dev here )我们知道Spyder的调试体验远非理想。我们现在提供的内容与标准的Python调试器非常相似,但是我们正在努力改进下一个主要版本的内容,以提供更接近科学家对调试器的期望(简而言之,一个常规的IPython控制台)您在当前断点处检查并绘制变量。)

现在谈谈你的观点:

  1. 这是真的。我们正在考虑改进这一点,以便如果用户按下Run按钮,并且当前文件中存在断点,则Spyder进入调试模式并执行程序直到满足第一个断点。

    < / LI>
  2. ipdb是IPython调试器控制台。不幸的是,由于IPython架构的限制,它非常有限(没有代码完成,也没有用箭头浏览历史记录)。此外,无法在ipdb或常规pdb控制台中运行任意Python代码。您可以在ipdb中运行的命令是在评估其中的help命令时可以阅读的命令。

  3. 那是因为,正如我所说,你无法评估任意Python代码。

  4. 您需要在我们的编辑器中添加新的断点,以便它们与我们的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

使用iPython%debug

快速首次调试
%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控制台进行调试,所以在开始调试之前选择控制台: enter image description here

如果有任何变量删除它们,请打开 variable explorer 。我使用 Ctrl + F5 开始调试,你可以使用顶部的按钮,但我更喜欢使用下面显示的快捷键:

enter image description here

(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的一个重要特性是,您有自动竞争,您可以使用变量资源管理器,而不是使用whatispp

enter image description here

使用变量资源管理器,您还可以更改变量的值,使事情变得更快。

条件断点

找到错误的另一个更聪明的方法是使用条件断点 Shift + F12 )Spyder的一大优势是调试并使用列表断点。当条件为True时,条件断点被激活在我们的例子中,我们想要找到b变为字符串的位置,因此条件为:type(b) == str。我通常会放置很多条件断点,看看哪个符合条件。为此,请不要使用 Shift + F12 ,但要在该行旁边双击普通断点,然后转到Debug-&gt;列出断点并复制并过去表中的条件到每个断点,如下图所示。

enter image description here

从这里开始使用的命令是:

(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。如果我在调试模式下更改脚本,我会这样做。

  1. 我关闭了当前的IPython(调试)控制台[x]
  2. 打开一个新菜单[菜单栏 - &gt; Consoles-&GT;打开一个IPython控制台]
  3. 再次进入调试模式[蓝色播放暂停按钮]。
  4. 还有点烦人,但它还有清除(重置)变量列表的额外好处。

答案 4 :(得分:0)

关于第3点的一点额外费用:

在我看来,调试控制台经常冻结,进行打印,评估等,但按下停止(退出调试)按钮通常会将其恢复到调用堆栈的底部,然后我可以重新启动('你正在调试的框架。值得一试。这可能适用于更高版本的Spyder(2.3.5.2)

答案 5 :(得分:0)

您可以使用调试快捷键,例如: 跳过F10 进入F11 在工具&gt;首选项&gt;键盘快捷键

答案 6 :(得分:0)

显然没有人提到过这两个:

在使用Python之前,我使用的是VBA。尽管它是一种相对较旧的语言,不会定期更新,但是我对VBA的一件事是调试功能。我遇到的最接近VBA或也可以称为“可视调试”的2个调试功能是:

  

1-PyCharm调试器

This 6分钟的视频演示了PyCharm调试器。

  

2-PixieDebugger-您一直想要的Jupyter笔记本的可视Python调试器

由于许多编码人员倾向于使用JupyterNotebook,因此该调试器会派上用场。 PixieDebugger与PyCharm调试器几乎相同。在这里我不会详细介绍。

但是您可以参考此link