Whoever writes a program must have a bug. To solve the bug, we need to debug the program. So in Python, there are several debugging tools, such as print, assert, logging, pdb, pdb.set_trace().
Printing directly using print() function
>>> def foo(s): ... n = int(s) ... print(n) ... return 10 / n ... >>> def main(): ... foo('0') ... >>> main() 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in main File "<stdin>", line 4, in foo ZeroDivisionError: division by zero
We can print variables where we think they might be wrong, but this has a big drawback, because the printed code has no real function, it's spam. And print has to be deleted at last, so the second method is to replace print with assert.
2. Use assert
>>> def foo(s): ... n = int(s) ... assert n != 0,'n The value is 0.!' ... return 10 / n ... >>> def main(): ... foo('0') ... >>> main() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in main File "<stdin>", line 3, in foo AssertionError: n The value is 0.!
Assert means that when the latter expression is False, Assertion Error is thrown, if True, do nothing and go straight to the next line. Assert has one major feature: when you start the python interpreter, you can use the - O parameter to close assert (uppercase o)
PS E:\Python3.6.3\workspace> python -O err_assert.py Traceback (most recent call last): File "err_assert.py", line 9, in <module> main() File "err_assert.py", line 7, in main foo('0') File "err_assert.py", line 4, in foo return 10 / n ZeroDivisionError: division by zer
3. Use logging
import logging logging.basicConfig(level=logging.INFO) s = '0' n = int(s) logging.info('n=%d' % n) print(10/n) #results of enforcement PS E:\Python3.6.3\workspace> python err_logginginfo.py INFO:root:n=0 Traceback (most recent call last): File "err_logginginfo.py", line 6, in <module> print(10/n) ZeroDivisionError: division by zero
Logging does not throw errors and outputs them directly to the file. Logging allows you to specify the level of logging information, from low to high, debug, info, warning, error, CRITICAL. When defining high level, low level information will not be output. This is to export log information to console. We can also export log information to file through setting.
4. Debugger pdb using python
The program can be executed in a one-step way, so that we can check the running status at any time.
New program err_pdb.py
s = '0' n = int(s) print(10 / n)
Then start in pdb mode
PS E:\Python3.6.3\workspace> python -m pdb err_pdb.py > e:\python3.6.3\workspace\err_pdb.py(1)<module>() -> s = '0' (Pdb) l 1 -> s = '0' 2 n = int(s) 3 print(10 / n) [EOF] (Pdb) n > e:\python3.6.3\workspace\err_pdb.py(2)<module>() -> n = int(s) (Pdb) p s '0' (Pdb) p n *** NameError: name 'n' is not defined (Pdb) n > e:\python3.6.3\workspace\err_pdb.py(3)<module>() -> print(10 / n) (Pdb) p n 0 (Pdb) p s '0' (Pdb) n ZeroDivisionError: division by zero > e:\python3.6.3\workspace\err_pdb.py(3)<module>() -> print(10 / n) (Pdb) n --Return-- > e:\python3.6.3\workspace\err_pdb.py(3)<module>()->None -> print(10 / n) (Pdb) n ZeroDivisionError: division by zero > <string>(1)<module>()->None (Pdb) n --Return-- > <string>(1)<module>()->None (Pdb) n Traceback (most recent call last): File "E:\Python3.6.3\lib\pdb.py", line 1667, in main pdb._runscript(mainpyfile) File "E:\Python3.6.3\lib\pdb.py", line 1548, in _runscript self.run(statement) File "E:\Python3.6.3\lib\bdb.py", line 431, in run exec(cmd, globals, locals) File "<string>", line 1, in <module> File "e:\python3.6.3\workspace\err_pdb.py", line 3, in <module> print(10 / n) ZeroDivisionError: division by zero Uncaught exception. Entering post mortem debugging Running 'cont' or 'step' will restart the program > e:\python3.6.3\workspace\err_pdb.py(3)<module>()->None -> print(10 / n) (Pdb) q Post mortem debugger finished. The err_pdb.py will be restarted > e:\python3.6.3\workspace\err_pdb.py(1)<module>() -> s = '0' (Pdb) n > e:\python3.6.3\workspace\err_pdb.py(2)<module>() -> n = int(s) (Pdb) q PS E:\Python3.6.3\workspace>
The lowercase letter l can list all the code to be executed. The n command represents one-step code execution. p is followed by the variable name, so you can see the value of the variable at any time. In pdb mode, changes to related variables are invalid for code that has not yet been executed in one step. The q command exits the current debugging, enters the debugging from scratch, enters q again, and then launches the debugging program. This way of debugging, there is a drawback, that is, can only be carried out step by step, if the program has many lines, is not tired to death.
5. Use pdb.set_trace()
#err_pdb.py import pdb s = '0' n = int(s) pdb.set_trace() #When the program runs here, it stops automatically and waits for commands. print(10 / n)
We can use l, c, n, p, q commands to control and view programs.
PS E:\Python3.6.3\workspace> python err_pdb.py > e:\python3.6.3\workspace\err_pdb.py(7)<module>() -> print(10 / n) (Pdb) p s '0' (Pdb) l 2 import pdb 3 4 s = '0' 5 n = int(s) 6 pdb.set_trace() #When the program runs here, it stops automatically and waits for commands. 7 -> print(10 / n) [EOF] (Pdb) n ZeroDivisionError: division by zero > e:\python3.6.3\workspace\err_pdb.py(7)<module>() -> print(10 / n) (Pdb) c Traceback (most recent call last): File "err_pdb.py", line 7, in <module> print(10 / n) ZeroDivisionError: division by zero