賴勇浩(http://laiyonghao.com)
之前我說過 python-message 與常見的 signal/slot 不同,處理函數不需要知道誰會發出一條資訊,而發出資訊的對象也不必知道是否有人處理它。這個與眾不同的特性,顯然有更寬廣的適用範圍,下面就是其中一個例子。
假定你在編寫一個非常牛X的程式庫,姑且為它取名為 foo,裡面有一個函數叫 bar,你就想啊,這麼牛X的一個函數,肯定要寫一下 log 啊,所以你就寫了以下代碼:
def bar():<br /> print 'Haha, Calling bar().'<br /> 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<br />LOG_MSG = ('log', 'foo')<br />def bar():<br /> message.pub(LOG_MSG, 'Haha, Calling bar().')<br /> do_sth()
而在你的項目中,只需要在項目開始處加上這樣的代碼:
import message<br />import foo<br />def handle_foo_log_msg(txt):<br /> print txt<br />message.sub(foo.LOG_MSG, handle_foo_log_msg)
而很類似地,在另一個項目 prjA 裡,你可以把 handle_foo_log_msg() 稍作修改:
def handle_foo_log_msg(txt):<br /> import logging<br /> logging.debug(txt)
在另一個 prjB 裡則可能是這樣:
import logging<br />logger = logging.getLogger("prjB")<br />def handle_foo_log_msg(txt):<br /> logger.debug(txt)
如果還有另一個 prjC 使用了其它的 log,相信此時你也可以輕鬆應對了,:)。