在Python web 開發框架里有多種選擇,有Django、Tornado、Flask、web2py、Pylons、Pyramid等等,之前寫過Django、Tornado,今天我們主要學習Pyramid,還是從官方文檔學起。
- 官方文檔
- 英文教程:https://docs.pylonsproject.org/projects/pyramid/en/latest/
- Creating Your First Pyramid Application
1.Pyramid
Pyramid 是 Pylons 項目下面一系列已經發行的軟件中的一員。Pylons 官網描述了 Pyramid 和 Pylons Project 的關系。
Pyramid以其高效率和快節奏的開發能力而出名。官方文檔是這樣描述的:Pyramid is a small, fast, down-to-earth Python web framework. It is developed as part of the Pylons Project. It is licensed under a BSD-like license. 此開源Web框架有一個獨立于平臺的MVC結構,提供了開發的最簡途徑。此外,它還是高效開發重用代碼的首選平臺之一。
Pyramid 和其他 web 框架(由Pyramid英文文檔翻譯)
第一個 Pyramid 版本的前生(叫做 repoze.bfg )創建于 2008 年。2010 年末,我們把 repoze.bfg 改名為 Pyramid 并于同年11月份合并到 Pylons 項目中。
Pyramid 的靈感來源于 Zope、Pylons 1.0 和 Django ,最終,Pyramid 向它們各自借鑒一些概念和特性并組成一個獨特的框架。
Pyramid 的許多特性都要追溯到 Zope 。像 Zope 應用程序一樣,Pyramid 應用程序是易于擴展的:如果你遵守一定的規則,那么你的應用程序將會被重用、改進、重構,甚至被第三方開發者擴展而不用 fork 原始程序。 Traversal 和 declarative security 等概念都是在 Zope 中首先被提出來的。
Pyramid 的 URL dispatch 概念受 Pylons 1.0 版本的 Routes 系統啟發的,Pyramid 像 Pylons 1.0 版本一樣采用自由政策。它沒有指定你應該使用哪個數據庫,它的內置模板只是為了方便。實際上,它僅僅提供一種將 URL 映射到 view 代碼上的機制,以及調用那些 views 的規則。你可以免費使用第三方組件來滿足你項目的需求。
Pyramid 經常使用的 view 這一概念來自 Django 。Pyramid 的文檔風格比起 Zope 更像 Django 。
類似 Pylons 1.0 版本,卻不像 Zope ,一個 Pyramid 應用程序開發者可以使用一個完整的語句命令去執行一個框架常用的配置任務比如增加一個 view 或者一個 route 。在 Zope 里面 ZCML 也有類似功能。Pyramid 支持隨時可用的命令語句配置和基于修飾符的配置;ZCML 通過一個擴展包 pyramd_zcml 使用。
既不像 Zope ,也不像 “full-stack” 這樣的框架比如 Django ,Pyramid 對于你使用哪一種持續化的機制構建應用程序不做任何假設。Zope 應用程序依賴于 ZODB;Pyramid 也允許你創建 ZODB 程序但卻不依賴 ZODB 本身。同樣,Django 傾向于假定你想要把你的應用程序數據存儲在一個關系型數據庫中。Pyramid 從不做這些假設,它允許你使用關系型數據庫但是不鼓勵也不阻止的決定。
其他的 Python web framework 都宣稱他們自己是一個類成員 web framework 叫做model-view-controller 框架,Pyramid 也屬于這一類。
框架 VS 庫 (由Pyramid英文文檔翻譯)
一個 框架 和一個 庫 最大的區別在于:庫里面的代碼被你寫的代碼 調用 ,而框架則是 調用 你寫的代碼。使用一系列的庫來創建應用程序通常在剛開始的時候要比使用框架簡單,因為你可以有選擇性地放棄一些控制權給不是你寫的庫代碼。但是當你使用一個框架的時候,你必須放棄絕大部分的控制權交給那些不是你寫的代碼:整個框架。你不是必須使用一個框架來創建一個 WEB 應用程序在使用 Python 的情況下。一大批豐富的庫都被已經被開發出來。然而在實際應用中,使用框架去創建應用要比使用一系列的庫更加實用,如果這個框架提供的一些列功能都符合你的項目要求。
2.Pyramid的安裝
官網講的還是蠻清楚的,照著來就行。
-
安裝setuptools
下載ez_setup.py(進入該頁面后網頁另存為ez_setup.py即可,記住存在D;\python目錄下)。cmd進入D:\python目錄,執行
python ez_setup.py
-
安裝virtualenv
用python目錄下的Script/easy_install程序安裝virtualenv:
easy_install virtualenv
- 用virtualenv創建工作區
virtualenv --no-site-packages env
-
安裝pyramid
執行完上面的步驟后應該多了一個env文件,cd env文件夾,然后執行
easy_install pyramid
3.Pyramid使用
1.創建第一個pyramid應用程序
from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.response import Response
def hello_world(request):
return Response('Hello %(name)s!'%request.matchdict)
if __name__ == '__main__':
#創建了一個Configuration類的實例config
config = Configurator()
#注冊了一個以/hello/開頭的URL路由,路由的名字就叫'hello'
config.add_route('hello','/hello/{name}')
#注冊了一個view callable函數 URL Path(比如/hello/world)->route(比如'hello')->view callable(比如hello_world函數)
config.add_view(hello_world,route_name='hello')
#pyramid.config.Configurator.make_wsgi_app()方法來創建WSGI應用程序
app = config.make_wsgi_app()
#啟動了一個WSGI服務
server = make_server('0.0.0.0',8080,app)
#serve_forever()方法創建了一個循環來接受外界的request請求
server.serve_forever()
打開你的瀏覽器,輸運行運行入http://localhost:8080/hello/world,將會顯示“Hello world!”。
現在我們對這個示例程序有了一個基本的認識,接下來一步一步分析它是如何工作的。
Imports 包
第2行引入了pyramid.config模塊的Configurator類,第10行創建了它的一個實例,然后通過這個實例來配置我們的應用。
跟其他Python web框架一樣,Pyramid 用 WSGI 協議來將一個應用程序和web服務器聯系到一起。而第一行用到的wsgiref模塊就是WSGI服務的一種封裝,現在wsgiref已經被引入Python 標準庫了。
第三行引入了pyramid.response.Response,用來返回response信息。View Callable 聲明
第六行定義了一個hello_world函數,傳入request參數,返回pyramid.response.Response類的一個實例。通過調用request對象的matchdict方法來輸入匹配到的name路徑。由于我們訪問的是http://localhost:8080/hello/world,所以匹配到的是world并以“hello world”的字符串返回,如果你訪問的是http://localhost:8080/hello/pyramid,那么返回的將是“hello pyramid!”。
這個函數被稱為 view callable(你可以叫它視圖調用,但我還是覺得用英文的比較好)。 一個視圖調用 接受一個參數:request 。 它將返回一個response 對象。 一個view callable不一定是一個函數,也可以是一個類或一個實例, 但是這里為了簡單起見,我們用了函數。
一個view callable總是伴隨著調用 request對象。 一個request對象就代表著一個通過被激活的WSGI服務器傳送到pyramid的HTTP請求。
一個view callable還需要返回一個response對象。因為一個response對象擁有所有來制定一個實際的HTTP 響應所必要的信息。這個對象通過 wsgi 服務器,也就是Pyramid,轉化為文本信息發送回請求的瀏覽器。為了返回一個response,每個view callable創建的一個response實例。在 hello_world函數中, 一個字符串作為response的body來返回。-
Application Configuration 應用程序配置
第10-15行是應用程序的配置信息。
第10行創建了一個Configuration類的實例config,通過這個實例來對我們的Pyramid應用進行配置,包括路由,ip,端口等信息。調用config的各種方法設置應用程序注冊表(application registry),對我們的應用程序進行注冊。什么是application registry?下面是官方解釋:
第11行調用pyramid.config.Configurator.add_route()方法,注冊了一個以/hello/開頭的URL路由,路由的名字就叫'hello'。
第12行config.add_v運行iew(hello_world, route_name='hello'),注冊了一個view callable函數(也就是hello_world函數),當名為'hello'的路由被匹配時應該調用這個函數。 這三者的對應關系也就是URL Path(比如/hello/world)->route(比如'hello')->view callable(比如hello_world函數)。這樣,一個前臺頁面就和一個后臺處理方法對應起來了。
WSGI Application Creation 創建WSGI應用程序
當所有的配置工作完成后,python腳本通過pyramid.config.Configurator.make_wsgi_app()方法來創建WSGI應用程序。這個方法返回一個WSGI應用程序對象并傳遞給app引用,讓WSGI服務器來使用。WSGI是一個讓服務器能和python應用程序交流的協議。這里不打算深入探討WSGI,如果你有興趣,可以去官網wsgi.org了解更多。
WSGI Application Serving
最后兩行,我們啟動了一個WSGI服務。make_server('0.0.0.0',8080,app)方法綁定了ip和端口,最后一個參數傳遞我們的app對象(一個router),也就是我們想服務的那個應用程序。serve_forever()方法創建了一個循環來接受外界的request請求。
4.Pyramid部分語法
locals()用法:locals()可以直接將函數中所有的變量全部傳給模板。當然這可能會傳遞一些多余的參數,有點浪費內存的嫌疑。
render()方法是render_to_response的一個嶄新的快捷方式,前者會自動使用RequestContext。而后者必須coding出來,這是最明顯的區別,當然前者更簡潔。
return render_to_response('blog_add.html',{'blog': blog,
'form': form, 'id': id, 'tag': tag},
context_instance=RequestContext(request))
return render(request, 'blog_add.html',
{'blog': blog, 'form': form, 'id': id, 'tag': tag})