如何在 Python 中使用 spyder 进行高效调试?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28280308/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:02:55  来源:igfitidea点击:

How do I debug efficiently with spyder in Python?

pythondebuggingspyder

提问by Hanan Shteingart

I like Python and I like Spyder but I find debugging with Spyder terrible!

我喜欢 Python 和 Spyder,但我发现使用 Spyder 进行调试很糟糕!

  • Every time I put a break point, I need to press two buttons: first the debug and then the continue button (it pauses at first line automatically) which is annoying.
  • Moreover, rather than having the standard iPython console with auto completion etc I have a lousy ipdb>> console which is just garbage.
  • The worst thing is that this console freezes very frequently even if I write prints or simple evaluation to try to figure out what is the bug. This is much worse than matlab.
  • Last but not least, if I call a function from within the ipdb>> console, and put a breakpoint in it, it will not stop there. It seems like I have to put the breakpoint there before I start the debugging (ctrl+F5).
  • 每次设置断点时,我都需要按两个按钮:首先是调试按钮,然后是继续按钮(它会自动在第一行暂停),这很烦人。
  • 此外,我有一个糟糕的 ipdb>> 控制台,而不是具有自动完成功能等的标准 iPython 控制台,它只是垃圾。
  • 最糟糕的是,即使我写了一些打印或简单的评估来试图找出错误所在,该控制台也会非常频繁地冻结。这比matlab差很多。
  • 最后但并非最不重要的是,如果我从 ipdb>> 控制台中调用一个函数,并在其中放置一个断点,它不会停在那里。似乎我必须在开始调试之前将断点放在那里(ctrl+F5)。

Do you have a solution or maybe can you tell me how you debug python scripts and functions?

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

I am using fresh install of Anaconda on a Windows 8.1 64bit.

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

采纳答案by Carlos Cordoba

(Spyder dev here) We're aware the debugging experience in Spyder is far from ideal. What we offer right now is very similar to the standard Python debugger, but we're working to improve things in our next major version to provide something closer to what any scientist would expect of a debugger (in short, a regular IPython console that lets you inspect and plot variables at the current breakpoint).

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

Now about your points:

现在谈谈你的观点:

  1. It's true. We're thinking to improve that so that if the user press the Run button, and there is a breakpoint present in the current file, then Spyder enters in debug mode and executes the program until the first breakpoint is met.

  2. ipdbis the IPython debugger console. Unfortunately, due to limitations in the IPython architecture, it's very limited (no code completion and no history browsing with arrows). Furthermore, it's not possible to run arbitrary Python code in either ipdbor a regular pdbconsole. The commands you can run in ipdbare the ones you can read when evaluate the helpcommand inside it.

  3. That's because, as I said, you can't evaluate arbitrary Python code.

  4. You need to put new breakpoints in our Editor so that they are synced with our Python/IPython consoles

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

  2. ipdb是 IPython 调试器控制台。不幸的是,由于 IPython 架构的限制,它非常有限(没有代码补全,也没有箭头浏览历史)。此外,不可能在任ipdbpdb控制台或常规控制台中运行任意 Python 代码。您可以运行的命令ipdb是您在评估其中的help命令时可以读取的命令。

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

  4. 您需要在我们的编辑器中放置新的断点,以便它们与我们的 Python/IPython 控制台同步

回答by Paul

One minor extra regarding point 3:

关于第 3 点的一个小补充:

It also seemed to me the debug console frequently froze, doing prints, evaluating, etc, but pressing the stop (Exit debug) button usually got it back to the bottom of the call stack and then I could go back up ('u') to the frame I was debugging in. Worth a try. This might be for a later version of Spyder (2.3.5.2)

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

回答by oogieoogieful

Here is how I debug in Spyder in order to avoid freezing the IDE. I do this if I alter the script while in debugging mode.

这是我在 Spyder 中调试以避免冻结 IDE 的方法。如果我在调试模式下更改脚本,我会这样做。

  1. I close out the current IPython (debugging) console [x]
  2. Open a new one [Menu bar-> Consoles-> Open an IPython Console]
  3. Enter debug mode again [blue play pause button].
  1. 我关闭了当前的 IPython(调试)控制台 [x]
  2. 新建一个【菜单栏->控制台->打开一个IPython控制台】
  3. 再次进入调试模式【蓝色播放暂停按钮】。

Still a bit annoying, but it has the added benefit of clearing (resetting) variable list.

仍然有点烦人,但它具有清除(重置)变量列表的额外好处。

回答by LtGlahn

The pdb debugger works just fine with regular python. So in Spyder, I just switch to the python console whenever I want to debug interactively.

pdb 调试器与常规 python一起工作得很好。所以在 Spyder 中,每当我想交互式调试时,我就切换到 python 控制台。

import pdb

def yourfunction():
    # Interesting stuff done here
    pdb.set_trace() 

Nice intro to debugging with pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/

使用 pdb 进行调试的不错介绍https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/

回答by G M

Debugging workflow

调试工作流

You have to understand that in fact you are using different integration of the Python debugger pdband ipdb(which uses pdband which can be accessed using the module ipdb). I hope this trivial example will help you with using it better.

您必须了解,实际上您正在使用Python 调试器的pdb不同集成和 ipdb(使用pdb和可以使用模块访问ipdb)。我希望这个简单的例子能帮助你更好地使用它。

Suppose you want to debug this code:

假设您要调试此代码:

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

Quick first debugging using iPython %debug

使用 iPython 进行快速第一次调试 %debug

%debug

The first thing I do is to call pdb from iPython using the magic command %debug, you can set it as a default mechanism using %pdb.

我做的第一件事是使用魔术命令从 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

Once you have lunch pdb. You can find all command in the official docsor you can use the command hto display them. In this stage the only commands that I use are:

一旦你吃午饭pdb。您可以在官方文档中找到所有命令,也可以使用该命令h来显示它们。在这个阶段,我使用的唯一命令是:

  • p: prints the variables that you specify
  • pp: pretty prints
  • args: if you are inside a function it prints the arguments
  • pp locals(): can be useful to print all the variables but most of the times it is a mess!
  • !use it if you want to avoid conflicts with the commands listed in h
  • whatisvariable_name: equivalent of type(variable_name)
  • u: Move the current frame one level up in the stack trace (to an older frame).
  • d: Move the current frame one level down in the stack trace (to a newer frame).
  • q: when you finish you can use q for quitting
  • p: 打印您指定的变量
  • pp: 漂亮的印花
  • args: 如果你在一个函数里面,它会打印参数
  • pp locals(): 打印所有变量很有用,但大多数时候它是一团糟!
  • !如果您想避免与中列出的命令发生冲突,请使用它 h
  • whatis变量名:相当于类型(变量名)
  • u:将当前帧在堆栈跟踪中向上移动一级(到较旧的帧)。
  • d:将当前帧在堆栈跟踪中向下移动一级(到更新的帧)。
  • q: 完成后可以使用 q 退出

In our case:

在我们的例子中:

ipdb> pp a,b,c,d
(25, '5', 456, '23')

Or ipdb> !a,b,c,d(no space between esclamation mark and first value). It's clear that b and d are strings in case we can use:

或者ipdb> !a,b,c,d(感叹号和第一个值之间没有空格)。很明显, b 和 d 是字符串,以防我们可以使用:

ipdb> whatis b
<type 'str'>

Going deeper using break-points

使用断点更深入

70% of the times %debugpoints you to the solution. When you need more features like breakpointsis time to use Spyder. In this case, we want to understand why bis a string we put a breakpoint next to it (double-clicking next to the line number in the editor window). I find much betterto use the standard Python console instead of the IPython console for debugging so select the console before starting debugging: enter image description here

70% 的时间会%debug指向您解决方案。当您需要更多像断点这样的功能时,是时候使用 Spyder 了。在这种情况下,我们想了解为什么b我们在一个字符串旁边放置了一个断点(在编辑器窗口中的行号旁边双击)。我发现使用标准 Python 控制台而不是 IPython 控制台进行调试要好得多,因此在开始调试之前选择控制台: 在此处输入图片说明

Then open the variable explorerif there are any variables delete them. I use Ctrl+F5to start the debugging you can use the buttons on the top but I prefer to use their shortcuts shown below:

然后打开 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

Now we have located the error. We can also test a solutionwe repeat the step until 12 and we set to_s = False

现在我们已经找到了错误。我们还可以测试一个解决方案,我们重复该步骤直到 12 并且我们设置to_s = False

(Pdb) to_s = False #!to_s = False to be on the safe side

It works. One important feature using the standard pdb in the Python console, is that you have auto competition and you can use the variable explorer instead of using whatisand pp:

有用。在Python 控制台中使用标准 pdb 的一项重要功能是,您可以进行自动竞争,并且可以使用变量资源管理器而不是使用whatispp

enter image description here

在此处输入图片说明

Using the variable explorer you can also change the value of the variables which makes the things even quicker.

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

Conditional breakpoints

条件断点

Another more clever way to locate the error is to use conditional breakpoint(Shift+F12) a great advantage of Spyder is going to debug and use list breakpoints. Conditional breakpoints are activated when the condition is TrueIn our case, we want to locate where b becomes a string so the condition is: type(b) == str. I usually place a lot of conditional breakpoints and see which ones meet the condition. For doing so don't use Shift+F12but place normal breakpoints double-clicking next to the line and go to Debug->List breakpoints and copy and past the condition in the table to every breakpoint as shown in the figure below.

定位错误的另一种更聪明的方法是使用条件断点( Shift+ F12) Spyder 的一大优势是调试和使用列表断点。当条件为时,条件断点被激活True在我们的例子中,我们想要定位 b 变成字符串的位置,所以条件是:type(b) == str。我通常会放置很多条件断点,看看哪些符合条件。为此,不要使用Shift+,F12而是在该行旁边双击放置正常断点,然后转到 Debug->List breakpoints 并将表中的条件复制并粘贴到每个断点,如下图所示。

enter image description here

在此处输入图片说明

From here the commands to use are:

从这里使用的命令是:

(Pdb) c  # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint

回答by Mahyar

You can use debug shortcut keys like: Step Over F10 Step Into F11 in tools>preferences>keyboard shortcuts

您可以使用调试快捷键,例如:在工具>首选项>键盘快捷键中步过 F10 步入 F11

回答by mcagriardic

No one has ever mentioned about these two before apparently:

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

Before Python, I was using VBA. Although it is a relatively old language that is not regularly updated, one thing I loved about VBA was the debugging function. The 2 debugging functions that are closest to VBA or which can also be termed as "visual debugging" I had come across are:

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

1-PyCharm Debugger

1-PyCharm 调试器

This6 minutes video demonstrates PyCharm debugger.

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

2-PixieDebugger - The Visual Python Debugger for Jupyter Notebooks You've Always Wanted

2-PixieDebugger - 您一直想要的 Jupyter Notebook 的可视化 Python 调试器

Since many coders tend to use JupyterNotebook, this debugger would come in handy. PixieDebugger is almost the same as PyCharm debugger. I will not go into detail in here.

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

But you can refer to this link

但是你可以参考这个链接