用 python-message 爲程序庫和日誌模塊解耦

賴勇浩(http://laiyonghao.com)
之前我說過 python-message 與常見的 signal/slot 不同,處理函數不需要知道誰會發出一條信息,而發出信息的對象也不必知道是否有人處理它。這個與衆不同的特性,顯然有更寬廣的適用範圍,下面就是其中一個例子。
假定你在編寫一個非常牛X的程序庫,姑且爲它取名爲 foo,裏面有一個函數叫 bar,你就想啊,這麼牛X的一個函數,肯定要寫一下 log 啊,所以你就寫了以下代碼:
def bar(): print 'Haha, Calling bar().' do_sth()
你高高興興發了版本,大家都過得很好。過了幾天,公司的另一個項目組聽聞牛人您寫了個庫叫 foo,非常好用,就拿去用了。當天,快下班的時候,你被拖去救火,因爲出 Bug 了呀。你查看了很久日誌,都沒有發現他們調用 bar() 的痕跡,一問,原來他們是用 logging 的,標準輸出在做 Daemon 的時候被重定向到 /dev/null 去了……。
好吧,你忍。但沒法忍啊,你們原來的項目又不用 logging,你在程序庫裏引入 logging 誰來初始化它呢?就算你引入了 logging,你們項目獲取 logger 可能是用 logging.getLogger('prjA'),另一個項目可能是用 logging.getLogger('prjB'),日後還有新項目呢,想到這個你就蛋疼了。忍痛割愛,把 print 語句給刪除掉?你又怕日後出了問題你自己都找不到 Bug 那還不是自己加班自己苦……。
這個時候,不妨讓 python-message 來幫你手,輕鬆改一下 bar() 函數
import message LOG_MSG = ('log', 'foo') def bar(): messeage.pub(LOG_MSG, 'Haha, Calling bar().') do_sth()
而在你的項目中,只需要在項目開始處加上這樣的代碼:
import message import foo def handle_foo_log_msg(txt): print txt message.sub(foo.LOG_MSG, handle_foo_log_msg)
而很類似地,在另一個項目 prjA 裏,你可以把 handle_foo_log_msg() 稍作修改:
def handle_foo_log_msg(txt): import logging logging.debug(txt)
在另一個 prjB 裏則可能是這樣:
import logging logger = logging.getLogger("prjB") def handle_foo_log_msg(txt): logger.debug(txt)
如果還有另一個 prjC 使用了其它的 log,相信此時你也可以輕鬆應對了,:)。

發佈了30 篇原創文章 · 獲贊 31 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章