調試 程序能一次寫完並正常執行的機率很小。總會有各類各樣的bug須要修正。 有的bug很簡單,看看錯誤信息就知道,有的bug很複雜,咱們須要知道出錯時 哪些變量的值是正確的,哪些變量的值是錯誤的,所以,須要一整套調試程序的手段來修復bug。 第一種方法:print 簡單直接粗暴有效,就是用print()把可能有問題的變量打印出來看看: def foo(s): n = int(s) print(">>>n = %d" % n) return 10 / n def main(): foo("0") main() 輸出結果: >>>n = 0 Traceback (most recent call last): File "C:/Python36/test.py", line 9, in <module> main() File "C:/Python36/test.py", line 7, in main foo("0") File "C:/Python36/test.py", line 4, in foo return 10 / n ZeroDivisionError: division by zero 用print()最大的壞處是未來還得刪除它,想一想程序裏處處都是print(),運行結果也會包含不少垃圾信息。 因此,咱們又有第二種方法。 第二種方法:斷言 凡是用print()來輔助查看的地方,均可以用斷言(assert)來代替: def foo(s): n = int(s) assert n != 0, "n is zero!" return 10 / n def main(): foo("0") main() assert的意思是,表達式 n!=0 應該是True,不然根據程序運行的邏輯,後面的代碼確定會出錯。 若是斷言失敗,assert語句自己就會拋出AssertionError: Traceback (most recent call last): File "C:/Python36/test.py", line 9, in <module> main() File "C:/Python36/test.py", line 7, in main foo("0") File "C:/Python36/test.py", line 3, in foo assert n != 0, "n is zero!" AssertionError: n is zero! 若是程序中處處充斥着assert,和print()相比也好不到哪去。 不過啓動python解釋器能夠用-o參數來關閉assert: $ python3 -O err.py Traceback (most recent call last): ... ZeroDivisionError: division by zero 關閉後,你能夠把全部的assert語句當成pas來看。 第三種方法:logging 把print()替換爲logging是第三種方式,和assert比,logging不會拋出錯誤,並且能夠輸出到文件。 import logging s = "0" n = int(s) logging.info("n = %d" % n) print(10 / n) 輸出結果: Traceback (most recent call last): File "C:/Python36/test.py", line 6, in <module> print(10 / n) ZeroDivisionError: division by zero >>> logging.info()就能夠輸出一段文本。 運行,發現除了ZeroDivisionError, 沒有任何信息。 怎麼回事呢? 別急,在import logging 以後添加一行配置再試試 import logging logging.basicConfig(level = logging.INFO) s = "0" n = int(s) logging.info("n = %d" % n) print(10 / n) 輸出結果: INFO:root:n = 0 Traceback (most recent call last): File "C:/Python36/test.py", line 7, in <module> print(10 / n) ZeroDivisionError: division by zero 看到輸出了吧,這就是使用logging的好處,它容許你指定記錄信息的級別 有debug,info,warning,error等幾個級別。 當咱們指定level = INFO時,logging.debug就不起做用了。 同理,指定level = WAENING後,debug和info就不起做用了。 這樣一來,擬具能夠放心地除數不一樣級別的I想你,也不用刪除,最後統一控制輸出哪一個級別的信息。 logging的另外一個好處就是經過簡單的配置,一條語句能夠同時輸出到不一樣的地方,好比console和文件。 第四種方法:pdb 第四種方式是移動python的調試器pdb,讓程序以單步方式運行,能夠隨時查看運行狀態。 咱們先來準備好程序: s = "0" n = int(s) print(10 / n) $ python3 -m pdb err.py > /Users/michael/Github/learn-python3/samples/debug/err.py(2)<module>() -> s = '0' 而後逐行輸入代碼檢查。 這種經過pdb在命令行調試的方法理論上是萬能的,可是實在太麻煩了。 IDE 若是要比較爽地設置斷點、單步執行,就須要一個支持調試功能的IDE。目前比較好的Python IDE有PyCharm: http://www.jetbrains.com/pycharm/ 另外,Eclipse加上pydev插件也能夠調試Python程序。 總結: 寫程序最痛苦的事情莫過於調試,程序每每會以你意想不到的流程來運行,你期待執行的語句其實根本沒有執行,這時候,就須要調試了。 雖然用IDE調試起來比較方便,可是最後你會發現,logging纔是終極武器。