在各種語言平臺(tái)中,python涌現(xiàn)的web框架恐怕是最多的,是一個(gè)百花齊放的世界,各種micro-framework、framework不可勝數(shù);猜想原因應(yīng)該是在python中構(gòu)造框架十分簡單,使得輪子不斷被發(fā)明。所以在Python社區(qū)總有關(guān)于Python框架孰優(yōu)孰劣的話題。下面就給大家介紹一下python的幾大框架:
1.DjangoDjango 應(yīng)該是最出名的py框架,Google App Engine甚至Erlang都有框架受它影響。
Django是走大而全的方向,它最出名的是其全自動(dòng)化的管理后臺(tái):只需要使用起ORM,做簡單的對象定義,它就能自動(dòng)生成數(shù)據(jù)庫結(jié)構(gòu)、以及全功能的管理后臺(tái)。
Django提供的方便,也意味著Django內(nèi)置的ORM跟框架內(nèi)的其他模塊耦合程度高。
應(yīng)用程序必須使用Django內(nèi)置的ORM,否則就不能享受到框架內(nèi)提供的種種基于其ORM的便利;理論上可以切換掉其ORM模塊,但這就相當(dāng)于要把裝修完畢的房子拆除重新裝修,倒不如一開始就去毛胚房做全新的裝修。
Django的賣點(diǎn)是超高的開發(fā)效率,其性能擴(kuò)展有限;采用Django的項(xiàng)目,在流量達(dá)到一定規(guī)模后,都需要對其進(jìn)行重構(gòu),才能滿足性能的要求。
而Django的缺點(diǎn)主要源自Django堅(jiān)持自己造所有的輪子,整個(gè)系統(tǒng)相對封閉,Django最為人詬病的地方有:
系統(tǒng)緊耦合,如果你覺得Django內(nèi)置的某項(xiàng)功能不是很好,想用喜歡的第三方庫來代替是很難的,比如下面將要說的ORM、Template。要在Django里用SQLAlchemy或Mako幾乎是不可能,即使打了一些補(bǔ)丁用上了也會(huì)讓你覺得非常非常別扭。
Django自帶的ORM遠(yuǎn)不如SQLAlchemy強(qiáng)大,除了在Django這一畝三分地,SQLAlchemy是Python世界里事實(shí)上的ORM標(biāo)準(zhǔn),其它框架都支持SQLAlchemy了,唯獨(dú)Django仍然堅(jiān)持自己的那一套。Django的 開發(fā)人員對SQLAlchemy的支持也是有 過討論和嘗試的,不過最終還是放棄了,估計(jì)是代價(jià)太高且跟Django其它的模塊很難合到一塊。
Template功能比較弱,不能插入Python代碼,要寫復(fù)雜一點(diǎn)的邏輯需要另外用Python實(shí)現(xiàn)Tag或Filter。Django的模板系統(tǒng)設(shè)計(jì)十分有意思,也應(yīng)該其框架內(nèi)影響最大、爭議最大的部分。
Django模板的設(shè)計(jì)哲學(xué)是徹底的將代碼、樣式分離;asp.net提倡將代碼/模板分離,但技術(shù)上還是可以混合;而Django則是從根本上杜絕在模板中進(jìn)行編碼、處理數(shù)據(jù)的可能。
比方說,asp.net模板中可以寫:
<%
int i;
for(i==0;i<10;i++){
....
}
%>
Django是徹底不支持嵌入類似上面的代碼,僅能使用其模板內(nèi)置的函數(shù);這實(shí)際上,是為其模板構(gòu)造了一種“新語言”;由于此“新語言”十分簡單,所以也能夠?qū)⑵淠0逡浦驳讲煌脚_(tái)。
大多數(shù)情況下,Django的模板功能是足夠的,但對于特殊(有時(shí)“特殊”也不是十分特殊)的情況,還是需要在模板中嵌入代碼,那么就需要根據(jù)其模板系統(tǒng)的規(guī)則做模板擴(kuò)展。有時(shí)候,模板中直接寫一行代碼能夠解決的問題,用模板擴(kuò)展實(shí)現(xiàn)后,會(huì)變成十幾行代碼。是否容忍在模板中編程,正是Django模板爭議最大之處。
Pylons & TurboGears & repoze.bfg
除了Django另一個(gè)大頭就是Pylons了,因?yàn)門urboGears2.x是基于Pylons來做的,而repoze.bfg也已經(jīng)并入Pylons project里這個(gè)大的項(xiàng)目里,后面不再單獨(dú)討論TurboGears和repoze.bfg了。
Pylons和Django的設(shè)計(jì)理念完全不同,Pylons本身只有兩千行左右的Python代碼,不過它還附帶有一些幾乎就是Pylons御用 的第三方模塊。Pylons只提供一個(gè)架子和可選方案,你可以根據(jù)自己的喜好自由的選擇Template、ORM、form、auth等組件,系統(tǒng)高度可 定制。我們常說Python是一個(gè)膠水語言(glue language),那么我們完全可以說Pylons就是一個(gè)用膠水語言設(shè)計(jì)的膠水框架。
選擇Pylons多是選擇了它的自由,選擇了自由的同時(shí)也預(yù)示著你選擇了噩夢:
學(xué)習(xí)噩夢,Pylons依賴于許多第三方庫,它們并不是Pylons造,你學(xué)Pylons的同時(shí)還得學(xué)這些庫怎么使用,關(guān)鍵有些時(shí)候你都不知道你 要學(xué)什么。Pylons的學(xué)習(xí)曲線相對比Django要高的多,而之前Pylons的官方文檔也一直是人批評的對象,好在后來出了The Definitive Guide to Pylons這本書,這一局面有所改觀。因?yàn)檫@個(gè)原因,Pylons一度被譽(yù)為只適合高手使用的Python框架。調(diào)試噩夢,因?yàn)闋可娴降哪K多,一旦有錯(cuò)誤發(fā)生就比較難定位問題處在哪里??赡苁悄銓懙某绦虻腻e(cuò)、也可能是Pylons出錯(cuò)了、再或是SQLAlchemy出錯(cuò)了、搞不好是formencode有bug,反正很凌亂了。這個(gè)只有用的很熟了才能解決這個(gè)問題。升級噩夢,安裝Pylons大大小小共要安裝近20個(gè)Python模塊,各有各自的版本號(hào),要升級Pylons的版本,哪個(gè)模塊出了不兼容的問題都有可能,升級基本上很難很難。至今reddit的Pylons還停留在古董的0.9.6上,SQLAlchemy也還是0.5.3的版本,應(yīng)該跟這條有關(guān)系。
Pylons和repoze.bfg的融合可能會(huì)催生下一個(gè)能挑戰(zhàn)Django地位的框架。
Tornado & web.py
Tornado( http://www.tornadoweb.org )是Facebook開源出來的框架,其哲學(xué)跟Django近乎兩個(gè)極端。Tornado即是一個(gè)Web server(對此本文不作詳述),同時(shí)又是一個(gè)類web.py的micro-framework。
Tornado走的是少而精的方向,它也有提供模板功能;雖然不鼓勵(lì),但作者是可以允許在模板進(jìn)行少量編碼(直接嵌入單行py代碼)的。
如果跟asp.net相比,Tornado有點(diǎn)類似僅實(shí)現(xiàn)了AsyncHttpHandler;除此之外,全部需要自己去實(shí)現(xiàn)。好吧,其實(shí)它有模板,有國際化支持,甚至還有內(nèi)置的OAuth/OpenID模塊,方便做第三方登錄,它其實(shí)也直接實(shí)現(xiàn)了Http服務(wù)器。但它沒有ORM(僅有一個(gè)mysql的超簡單封裝),甚至沒有Session支持,更不要說Django那樣自動(dòng)化的后臺(tái)。
假設(shè)是一個(gè)大型網(wǎng)站,在高性能的要求下,框架的各個(gè)部分往往都需要制,可以復(fù)用的模塊非常少;一個(gè)以Django開發(fā)的網(wǎng)站,各部分經(jīng)過不斷的定制,Django框架剩下的,很有可能也就是tornado一開始所能提供的這部分。
2.HTTP服務(wù)器Tornado為了高效實(shí)現(xiàn)Comet/后端異步調(diào)用HTTP接口,是直接內(nèi)嵌了HTTP服務(wù)器。
前端無需加apache / lighttpd / nginx等也可以供瀏覽器訪問;但它并沒有完整實(shí)現(xiàn)HTTP 1.1的協(xié)議,所以官方文檔是推薦用戶在生產(chǎn)環(huán)境下在前端使用nginx,后端反向代理到多個(gè)Tornado實(shí)例。
Tornado本身是單線程的異步網(wǎng)絡(luò)程序,它默認(rèn)啟動(dòng)時(shí),會(huì)根據(jù)CPU數(shù)量運(yùn)行多個(gè)實(shí)例;充分利用CPU多核的優(yōu)勢。
單線程異步
網(wǎng)站基本都會(huì)有數(shù)據(jù)庫操作,而Tornado是單線程的,這意味著如果數(shù)據(jù)庫查詢返回過慢,整個(gè)服務(wù)器響應(yīng)會(huì)被堵塞。
數(shù)據(jù)庫查詢,實(shí)質(zhì)上也是遠(yuǎn)程的網(wǎng)絡(luò)調(diào)用;理想情況下,是將這些操作也封裝成為異步的;但Tornado對此并沒有提供任何支持。
一個(gè)系統(tǒng),要滿足高流量;是必須解決數(shù)據(jù)庫查詢速度問題的!
數(shù)據(jù)庫若存在查詢性能問題,整個(gè)系統(tǒng)無論如何優(yōu)化,數(shù)據(jù)庫都會(huì)是瓶頸,拖慢整個(gè)系統(tǒng)!
異步并不能從本質(zhì)上提到系統(tǒng)的性能;它僅僅是避免多余的網(wǎng)絡(luò)響應(yīng)等待,以及切換線程的CPU耗費(fèi)。
如果數(shù)據(jù)庫查詢響應(yīng)太慢,需要解決的是數(shù)據(jù)庫的性能問題;而不是調(diào)用數(shù)據(jù)庫的前端Web應(yīng)用。對于實(shí)時(shí)返回的數(shù)據(jù)查詢,理想情況下需要確保所有數(shù)據(jù)都在內(nèi)存中,數(shù)據(jù)庫硬盤IO應(yīng)該為0;這樣的查詢才能足夠快;而如果數(shù)據(jù)庫查詢足夠快,那么前端web應(yīng)用也就無將數(shù)據(jù)查詢封裝為異步的必要。就算是使用協(xié)程,異步程序?qū)τ谕匠绦蚴冀K還是會(huì)提高復(fù)雜性;需要衡量的是處理這些額外復(fù)雜性是否值得。如果后端有查詢實(shí)在是太慢,無法繞過,Tornaod的建議是將這些查詢在后端封裝獨(dú)立封裝成為HTTP接口,然后使用Tornado內(nèi)置的異步HTTP客戶端進(jìn)行調(diào)用
本文版權(quán)歸黑馬程序員Python培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:黑馬程序員Python培訓(xùn)學(xué)院
首發(fā):http://pantone-color.com.cn/news/python.html