问题
I like Python and I like Spyder but I find debugging with Spyder terrible!
- 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).
Do you have a solution or maybe can you tell me how you debug python scripts and functions?
I am using fresh install of Anaconda on a Windows 8.1 64bit.
回答1:
(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).
Now about your points:
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.
ipdb
is 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 eitheripdb
or a regularpdb
console. The commands you can run inipdb
are the ones you can read when evaluate thehelp
command inside it.That's because, as I said, you can't evaluate arbitrary Python code.
You need to put new breakpoints in our Editor so that they are synced with our Python/IPython consoles
回答2:
Debugging workflow
You have to understand that in fact you are using different integration of the Python debugger pdb and ipdb (which uses pdb
and which can be accessed using the module ipdb). I hope this trivial example will help you with using it better.
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
%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
.
%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 docs or you can use the command h
to display them. In this stage the only commands that I use are:
p
: prints the variables that you specifypp
: pretty printsargs
: if you are inside a function it prints the argumentspp 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 inh
whatis
variable_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
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> whatis b
<type 'str'>
Going deeper using break-points
70% of the times %debug
points you to the solution. When you need more features like breakpoints is time to use Spyder. In this case, we want to understand why b
is a string we put a breakpoint next to it (double-clicking next to the line number in the editor window). I find much better to use the standard Python console instead of the IPython console for debugging so select the console before starting debugging:
Then open the variable explorer
if there are any variables delete them. I use Ctrl+F5 to start the debugging you can use the buttons on the top but I prefer to use their shortcuts shown below:
(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 solution we repeat the step until 12 and we set 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 whatis
and pp
:
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 True
In 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+F12 but 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.
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
回答3:
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.
import pdb
def yourfunction():
# Interesting stuff done here
pdb.set_trace()
Nice intro to debugging with pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/
回答4:
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.
- I close out the current IPython (debugging) console [x]
- Open a new one [Menu bar-> Consoles-> Open an IPython Console]
- Enter debug mode again [blue play pause button].
Still a bit annoying, but it has the added benefit of clearing (resetting) variable list.
回答5:
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:
1-PyCharm Debugger
This 6 minutes video demonstrates PyCharm debugger.
2-PixieDebugger - The Visual Python Debugger for Jupyter Notebooks You’ve Always Wanted
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.
But you can refer to this link
回答6:
One minor extra regarding point 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)
回答7:
You can use debug shortcut keys like: Step Over F10 Step Into F11 in tools>preferences>keyboard shortcuts
来源:https://stackoverflow.com/questions/28280308/how-do-i-debug-efficiently-with-spyder-in-python