寫程式時, 通常會先驗証邏輯計算是否正確. 比如要將資料寫入資料庫, 當然不會在寫完資料收集的程式碼後, 就馬上接著寫連線資料庫的程式. 總得要先列印出來看看抓到的資料是否正確嘛, 不然寫入資料庫的資料都是錯了, 資料庫不就整個毀了.
列印資料, 當然就是用print()印到螢幕上檢查囉. 另外某個變數, 計算後的結果是不是符合我們的期待, 也通常會先印出來看看.
print()好用歸好用, 但當測試完後, 就要手動刪除, 不然留著一直列印, 是很消耗CPU的資源的.
Assert
中文是斷言的意思. 這好比是在發誓一樣~~我發誓我一定會變有錢人, 不然你就給它爛掉.
assert n!=0, ‘除到0了啦’
前面的 n!=0就是在發誓, 後面的字串就是沒有達成的後果
當前面的保証沒達成, 就會發送AssertionError的例外, 此例外的訊息就是後面的那串字串.
def math(x, y): assert y!=0, "除到0了啦" return x/y def main(): try: r=math(10,0) except AssertionError as e: print(e) if __name__=="__main__": main() 結果 : 除到0了啦
當然一大堆assert也是很煩的, 所以可以在執行程式時, 下達大寫的O關閉 assert的動作
python -O myapp.py
logging
logging.info(‘字串’) 是用來取代print()的, 它就是直接把字串印出來而以. 但可以利用level等級來控制何時要列印. Logging才是程式debug的終極武器.
import logging logging.basicConfig(level=logging.INFO) def math(x, y): logging.info('y的值為 %d' % y) return x/y def main(): try: r=math(10,0) except ZeroDivisionError: pass if __name__=="__main__": main() 結果 : INFO:root:y的值為 0
level共有四個等級, debug, info, warning, error. Debug 等級最低, 無論什麼狀況都會執行, error最高, 只有發生錯誤時才會執行.
pdb
pdb是python的單行執行除錯器, 可以一步一步的執行
python -m pdb myapp.py
進入互動模式後可以執如下指令
n : 下一步
l : 是小寫的L, list的意思, 把程式碼印出,並會有箭頭指向目前執行的位置
p 變數名 : 列出變數的值
q : 結束單行偵測
(Pdb) l 7 try: 8 r=math(10,0) 9 except ZeroDivisionError: 10 pass 11 if __name__=="__main__": 12 -> main() [EOF]
pdb.set_trace()
pdb.set_trace()是設定一個中斷點, 也就是執行到此處就停止, 進入pdb互動模式, 同樣也是 p 變數 可列印變數直, n是下一步, c 繼續執行.
import logging import pdb logging.basicConfig(level=logging.WARNING) def math(x, y): logging.info('y的值為 %d' % y) pdb.set_trace() return x/y def main(): try: r=math(10,0) except ZeroDivisionError: pass if __name__=="__main__": main()
IDE設定中斷點
在行數旁按一下, 會出現紅色的點, 右按鍵選擇”All”, 然後從 Run/debug xxx.py即可