2012年1月16日 星期一

Python debug 的方法

有別於 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 確實還是有它的難處, 不過該寫的東西之前寫得差不多了, 有興趣的人請翻翻舊文。

1 則留言:

  1. ipython <= 0.10,有時要:
    IPython.Shell.IPShellEmbed(argv=[])()

    這樣 ipython 才不會去取處 command line 參數

    回覆刪除

在 Fedora 下裝 id-utils

Fedora 似乎因為執行檔撞名,而沒有提供 id-utils 的套件 ,但這是使用 gj 的必要套件,只好自己編。從官網抓好 tarball ,解開來編譯 (./configure && make)就是了。 但編譯後會遇到錯誤: ./stdio.h:10...