Error debugging of python

Keywords: Python

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

Posted by chadtimothy23 on Tue, 23 Apr 2019 15:09:35 -0700