>>> 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
咱們能夠在認爲可能出錯的地方打印變量,但這有很大的弊端,由於打印的代碼沒有實際功能,都是垃圾信息。並且print最後還得刪除,因此第二種方法是用assert替代printpython
>>> def foo(s): ... n = int(s) ... assert n != 0,'n的值是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的值是0!
assert的意思,當後面的表達式爲False時,就會拋出AssertionError,若是爲True,什麼都不作,直接到下一行。assert有一大特性:在啓動python解釋器的時候可使用-O參數來關閉assert(大寫的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
import logging logging.basicConfig(level=logging.INFO) s = '0' n = int(s) logging.info('n=%d' % n) print(10/n) #執行結果 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不會拋出錯誤,直接輸出到文件中。logging能夠容許你指定記錄信息的級別,級別由低到高分別是debug、info、warning、error、CRITICAL等級別,當定義高級別的時候,低級別的信息不會輸出,這是把日誌信息輸出到控制檯console,咱們還能夠經過設置把日誌輸出到文件中post
可讓程序以單步方式執行,方便咱們隨時查看運行狀態spa
新建程序err_pdb.pydebug
s = '0' n = int(s) print(10 / n)
而後以pdb模式啓動調試
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>
小寫字母l,能夠列出全部要執行的代碼;
n 命令表示單步執行代碼;
p 後面加上變量名,能夠隨時查看變量的值;
在pdb模式中,對於尚未單步執行到的代碼,相關的變量的變動是無效的;
q 命令退出當前調試,進入從新從頭開始調試,再次輸入q,就會推出調試程序。
這種方式的調試,有一個弊端,就是隻能一步一步的執行下去,若是程序有不少行,豈不是累死。
#err_pdb.py import pdb s = '0' n = int(s) pdb.set_trace() #程序運行到這裏會自動中止,等待命令 print(10 / n)
咱們可使用l、c、n、p、q等命令來控制和查看程序rest
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() #程序運行到這裏會自動中止,等待命令 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