當你在Python的世界中冒險,突然遭遇一隻Web怪獸,你會選擇什麼武器對付它?在兵器譜上,下列兵器可謂名列前茅:
- Zope,厚重的長槍。較早出現的武器形態。該武器非常之強悍,無堅不摧,無物不破。而且適合在軍隊中使用,排兵布陣集團作戰效果更佳。然而要用好Zope要花上很長的時間,俗話說“月棍年刀一輩子槍”,可見其難度。
- TurboGears,威武的刀。快意江湖必備之物。其打造者熟知江湖規矩,頗有武林盟主之風,遇事通常拉幫結夥,指派任務,決計不會把所有事情都攬在自己身上。
- Django,飄逸的劍。非常內斂,據說使用該武器的高手通常是獨行俠,他們的格言是:一劍在手,夫複何求?
- Web.py,小巧的匕首,刺客的最愛。常被用來執行特殊任務。
- pylons,詭異的鞭, 傳言是Ruby世界的rails披上了Python的外衣,使用起來一定要小心,因為你不知道它會纏住敵人的脖子還是自己的脖子。
然而,我們今天要說的並不是這些武器,而是一種心法。畢竟武器的使用只是“招法”,而心法是招法的靈魂,心法一通,招法百通。這就是由馬里奧創造的“管道心法”,西方大陸稱其為WSGI(Python web服務網關介面)。
馬里奧是一位水管工,常年鑽在水管中苦心研究武術。馬里奧發現,其實武器無所謂高下,最重要的是看使用武器的人和你要對付的對象。所謂一寸長,一份強,如Zope威力強大,用來對付大型怪獸很合適,卻難免滯重;而一寸短,一份險,如web.py在應付小型靈敏怪獸時有其獨特優勢。所以單單評論武器的優劣根本是空泛之談。於是乎,馬里奧在水管中冥思苦想十餘載,終於發現了適用於所有武器的心法。掌握此心法,使用任何武器都能遊刃有餘。由於馬里奧是在水管中受到了啟發,故命名為“管道心法”。本文作者在遊歷時有幸發現此心法,並在“心內求法”上流傳出來。傳說上古時期的大神道格拉斯·麥克羅伊在參與創世時,曾經構築了稱為Pipeline的時空奇點,用以串連stdout和stdin。馬里奧是否受此啟發我們不得而知,但“管道心法”確實與此有類似之處:
WSGI是馬里奧在探索管道的時候發現的一種串連件,它非常簡單,入口處提供一個start_response,用於迴流(回調,callback),入口會串連到出口的一個函數,並傳遞environ字典和start_response作為參數;而出口處的函數先是調用start_response並傳遞status和header,然後再返回content。由於這段心法有些拗口,馬里奧示範了唯一的招式,並聲明其實所有的招式都可以從這招中演化出來:
def application(environ, start_response):
status = '200 OK'
response_headers = [('Content-type','text/plain')]
start_response(status, response_headers)
return ['Hello']
馬里奧還發現,WSGI其實可以串聯起來,為了區分,馬里奧將下水管的入口叫做web server,只能接受外界的請求並調用下一段管件的函數;中間的管件叫做middleware,既可以接收上一段管件的請求,又可以調用下一段管件的函數;管道的終點叫做web app,只能被上一段管件調用。
為了避免後人誤解,馬里奧最後強調:武器是死的,好的武器只有在合適的人手裡才能發揮最大的威力,爭執於武器的好壞毫無意義。
馬里奧最後將這段心法奉獻給了PEP,PEP將其編號為333。