Debugging
From:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/ 00138683229901532c40b749184441dbd428d2e0f8aa50e000
the probability that the program can be completed once and run normally is very small, not more than 1%. There will always be a variety of bugs to fix. Some bugs are simple, look at the error message and know that some bugs are complicated, we need to know which variables are correct, and which values are wrong, so a full set of debug programs is required to fix the bug.
The first method is simple and straightforward, which is to print
print out the variables that might be problematic:
# err.pydef foo(s): n = int(s) print ‘>>> n = %d‘ % n return 10 / ndef main(): foo(‘0‘)main()
After execution, look for the printed variable value in the output:
call last): ...ZeroDivisionError: integer division or modulo by zero
print
The biggest disadvantage is to delete it in the future, think about the program is everywhere print
, the results will contain a lot of junk information. So, we have a second method.
Assertion
print
any place that is used to assist in viewing can be replaced by an assertion (assert):
# err.pydef foo(s): n = int(s) assert n != 0, ‘n is zero!‘ return 10 / ndef main(): foo(‘0‘)
assert
This means that the expression n != 0
should be True
, otherwise, the subsequent code will go wrong.
If the assertion fails, the assert
statement itself is thrown AssertionError
:
call last): ...AssertionError: n is zero!
If the program is filled with everywhere assert
, and print
compared to where to go. However, you can use -O
parameters to turn off the Python interpreter when you start it assert
:
call last): ...ZeroDivisionError: integer division or modulo by zero
After closing, you can take all the assert
statements as a pass
look.
Logging
print
Replace with the logging
3rd way, and the assert
ratio, logging
will not throw an error, and can be output to a file:
# err.pyimport loggings = ‘0‘n = int(s)logging.info(‘n = %d‘ % n)print 10 / n
logging.info()
You can output a piece of text. Run, found in addition ZeroDivisionError
, without any information. What's going on?
Don't worry, import logging
add a line after the configuration and try again:
import logginglogging.basicConfig(level=logging.INFO)
See the output:
call last): File "err.py", line 8, in <module> print 10 / nZeroDivisionError: integer division or modulo by zero
This is logging
the benefit that allows you to specify the level of logging information, there,, and debug
info
so on warning
error
several levels, when we specify level=INFO
, it logging.debug
will not work. Similarly, after the designation level=WARNING
, debug
and info
will not work. This way, you can confidently output different levels of information, do not delete, and finally unified control the output of which level of information.
logging
Another benefit is that with a simple configuration, a single statement can be output to a different place at the same time, such as the console and the file.
Pdb
The 4th Way is to launch the Python debugger pdb, to let the program run in a single step, and to view the running state at any time. Let's prepare the program:
# err.pys = ‘0‘n = int(s)print 10 / n
Then start:
$ python -m pdb err.py> /Users/michael/Github/sicp/err.py(2)<module>()-> s = ‘0‘
When started with a parameter -m pdb
, the PDB navigates to the code to be executed next -> s = ‘0‘
. Enter a command l
to view the code:
(Pdb) l 1 # err.py 2 -> s = ‘0‘ 3 n = int(s) 4 print 10 / n[EOF]
Enter a command n
to step through the code:
(Pdb) n> /Users/michael/Github/sicp/err.py(3)<module>()-> n = int(s)(Pdb) n> /Users/michael/Github/sicp/err.py(4)<module>()-> print 10 / n
You can enter a command at any time p 变量名
to view the variable:
(Pdb) p s‘0‘(Pdb) p n0
Enter command q
to end debugging, exit the program:
(Pdb) nZeroDivisionError: ‘integer division or modulo by zero‘> /Users/michael/Github/sicp/err.py(4)<module>()-> print 10 / n(Pdb) q
This method of debugging through the PDB in the command line is theoretically omnipotent, but it is too cumbersome, if there are 1000 lines of code, to run to the No. 999 line to knock how many commands ah. Fortunately, we have another debugging method.
Pdb.set_trace ()
This method also uses the PDB, but does not need to be single-step, we only need import pdb
, and then, in the place where there may be error pdb.set_trace()
, we can set a breakpoint:
# err.pyimport pdbs = ‘0‘n = int(s)pdb.set_trace() # 运行到这里会自动暂停print 10 / n
Running the code, the program automatically pdb.set_trace()
pauses and goes into the PDB debugging environment, you can view the variable with a command p
, or continue running with a command c
:
call last): File "err.py", line 7, in <module> print 10 / nZeroDivisionError: integer division or modulo by zero
This is much more efficient than a direct-start PDB, but it's also a high-level one.
Ide
If you want to set breakpoints more easily, step into it, you need an IDE that supports debugging capabilities. The better Python IDE now has pycharm:
http://www.jetbrains.com/pycharm/
In addition, the Eclipse plus Pydev plugin can also debug Python programs.
Summary
Several ways to debug python