有別於 C/C++, Python 通常會有原始碼, 除非套件提供者無腦地用 egg 包裝, 不然應該滿好改程式碼的 (我討厭 egg!! 其實這有雙關, 不過 ...)。再加上使用 virtualenv 擁有自己安裝的函式庫, 這樣和別人共用 server 時, 不用擔心改函式庫的程式會影響到別人, 相當方便。
在這樣方便改程式的情況下, 通常我會採下列三種方法之一來觀察程式 (或除錯):
使用 IPython
在要觀察程式的地方寫入
import IPython IPython.Shell.IPShellEmbed(argv=[])() # 舊版 IPython.embed() # 新版我甚至寫了個 vim 巨集展開這段。
使用 pdb
import pdb; pdb.set_trace()效果類以上一個, 不過應該是 ipython 更易操作。或許也可考慮用 IPython pdb。習慣用 gdb 看 backtrace 的話, 用 pdb 滿直覺的。
使用 logger
配合 decorator 的語法, python 要觀察特定函式容易許多, 如這篇提到的做法, 寫個 decorator "log", 配合 lazy initialization 的方式設定 logging。之後只要在有興趣的幾個函式上加個 @log 即可。
這個作法應用的範圍更大, 像在 WSGI 沒 console 可用, 也不能輸出到 STDOUT, 用這招就沒問題。還有, 這個作法也可在 production 環境記錄關鍵函式的執行速度, 協助 profiling。
題外話
若是要除錯的話, 視情況用 unit test 會更好, 原因見《為什麼要寫 unit test?為什麼要先寫測試?》。在見識過 C/C++ 的困難處後, 覺得在 Python 的環境裡寫 test 實在是太輕鬆寫意了, 雖說寫 test 確實還是有它的難處, 不過該寫的東西之前寫得差不多了, 有興趣的人請翻翻舊文。
ipython <= 0.10,有時要:
回覆刪除IPython.Shell.IPShellEmbed(argv=[])()
這樣 ipython 才不會去取處 command line 參數