入門python tornado介紹中文翻譯你像從前一樣_第1頁
入門python tornado介紹中文翻譯你像從前一樣_第2頁
入門python tornado介紹中文翻譯你像從前一樣_第3頁
入門python tornado介紹中文翻譯你像從前一樣_第4頁
入門python tornado介紹中文翻譯你像從前一樣_第5頁
已閱讀5頁,還剩106頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第一章:引言本書出處:中文翻譯:你像從前一樣在過去的五年里,Web開發(fā) 的可用工具實(shí)現(xiàn)了 式地增長。當(dāng)技術(shù) 不斷推動(dòng)極限,使Web應(yīng)用無處不在時(shí), 也不得不升級(jí) 的工具、創(chuàng)建框架以保證構(gòu)建更好的應(yīng)用。 希望能夠使用新的工 具,方便 寫出更加整潔、可 的代碼,使部署到世界各地的用戶時(shí)擁有高效的可擴(kuò)展性。這就讓 談?wù)摰絋ornado,一個(gè)編寫易創(chuàng)建、擴(kuò)展和部署的強(qiáng)力Web應(yīng)用的夢幻選擇。 三個(gè)都因?yàn)?Tornado的速度、簡單和可擴(kuò)展性而深深地愛上了它,在一些個(gè)人項(xiàng)目中嘗試之后, 其運(yùn)用到日常工作中。 已經(jīng)看到,Tornado在很多大型或小型的項(xiàng)目中 了開發(fā)者的速度(和樂趣?。?,同時(shí),其魯棒性和輕

2、量級(jí)也給開發(fā)者一次又一次留下了深刻的印象。本書的目的是對Tornado Web服務(wù)器進(jìn)行一個(gè)概述,通過框架基礎(chǔ)、一些示例應(yīng)用和真實(shí)世界使用的最佳實(shí)踐來引導(dǎo)讀者。 使用示例來詳細(xì)講解Tornado如何工作,你可以用它做什么,以及在構(gòu)建自己第 一個(gè)應(yīng)用時(shí)要避免什么。 在本書中, 假定你對 已經(jīng)有了粗略的了解,知道Web服務(wù)如何 ,對數(shù)據(jù)庫有一定的熟悉。 有一些不錯(cuò)的書籍可以為你深入了解這些提供參考(比如Learning ,Restful Web Service和 MongoDB: The Definitive Guide)。你可以在 上獲得本書中示例的代碼。如果你有關(guān)于這些示例或其他方面的任何 ,

3、歡迎在那里告 訴 。所以,事不宜遲,讓 開始深入了解吧!Tornado是什么?Tornado入門社區(qū)和支持簡單的Web服務(wù)o Tornado字符串服務(wù)關(guān)于Reques ndler的 知識(shí)下一步1.1 Tornado是什么?Tornado是使用 編寫的一個(gè)強(qiáng)大的、可擴(kuò)展的Web服務(wù)器。它在處理嚴(yán)峻的網(wǎng)絡(luò)流量時(shí)表現(xiàn)得足夠強(qiáng)健,但卻在創(chuàng)建和編寫時(shí)有著足夠的輕量級(jí),并能夠被用在大量的應(yīng)用和工具中。- 1 -現(xiàn)在所知道的Tornado是基于Bret Taylor和其他 為FriendFeed所開發(fā)的網(wǎng)絡(luò)服務(wù)框架,當(dāng) FriendFeed被 收購后得以開源。不同于那些最多只能達(dá)到10,000個(gè)并發(fā)連接的傳

4、統(tǒng)網(wǎng)絡(luò)服務(wù)器,Tornado在設(shè)計(jì)之初就考慮到了性能 ,旨在解決C10K問題,這樣的設(shè)計(jì)使得其成為一個(gè)擁有非常高性能的框架。此外,它還擁有處理安全性、用戶驗(yàn)證、社交網(wǎng)絡(luò)以及與外部服務(wù)(如數(shù)據(jù)庫和 API) 進(jìn)行異步交互的工具。延伸閱讀:C10K問題基于線程的服務(wù)器,如Apache,為了傳入的連接, 了一個(gè)操作系統(tǒng)的線程池。Apache會(huì)為每個(gè) HTTP連接分配線程池中的一個(gè)線程,如果所有的線程都處于被占用的狀態(tài)并且尚有內(nèi)存可用時(shí),則生成一個(gè)新的線程。盡管不同的操作系統(tǒng)會(huì)有不同的設(shè)置,大多數(shù)Linux發(fā)布版中都是默認(rèn)線程堆大小為 8MB。Apache的架構(gòu)在大負(fù)載下變得不可 ,為每個(gè)打開的連接

5、一個(gè)大的線程池等待數(shù)據(jù)極易迅速耗光服務(wù)器的內(nèi)存資源。大多數(shù)社交網(wǎng)絡(luò)應(yīng)用都會(huì)展示實(shí)時(shí)更新來提醒新消息、狀態(tài)變化以及用戶通知,這就要求客戶端需要保持 一個(gè)打開的連接來等待服務(wù)器端的任何響應(yīng)。這些長連接或推送請求使得Apache的最大線程池迅速飽和。 一旦線程池的資源耗盡,服務(wù)器將不能再響應(yīng)新的請求。異步服務(wù)器在這一場景中的應(yīng)用相對較新,但他們正是被設(shè)計(jì)用來減輕基于線程的服務(wù)器的限制的。當(dāng)負(fù) 載增加時(shí),諸如Node.js,lighttpd和Tornodo這樣的服務(wù)器使用協(xié)作的多任務(wù)的方式進(jìn)行優(yōu)雅的擴(kuò)展。也 就是說,如果當(dāng)前請求正在等待來自其他資源的數(shù)據(jù)(比如數(shù)據(jù)庫查詢或HTTP請求)時(shí),一個(gè)異步服務(wù)

6、器 可以明確地控制以掛起請求。異步服務(wù)器用來恢復(fù)暫停的操作的一個(gè)常見模式是當(dāng)合適的數(shù)據(jù)準(zhǔn)備好時(shí)調(diào) 用回調(diào)函數(shù)。 會(huì)在第五章講解回調(diào)函數(shù)模式以及一系列Tornado異步功能的應(yīng)用。自從2009年9月10日發(fā)布以來,TornadoTornado已經(jīng)獲得了很多社區(qū)的支持,并且在一系列不同的場合 得到應(yīng)用。除FriendFeed和 外,還有很多公司在生產(chǎn)上轉(zhuǎn)向Tornado,包括Quora、 Turntable.fm、Bit.ly、Hipmunk以及MyYearbook等。總之,如果你在尋找你那龐大的CMS或 開發(fā)框架的替代品,Tornado可能并不是一個(gè)好的選擇。 Tornado并不需要你擁有龐大的

7、模型建立特殊的方式,或以某種確定的形式處理表單,或其他類似的事 情。它所做的是讓你能夠快速簡單地編寫高速的Web應(yīng)用。如果你想編寫一個(gè)可擴(kuò)展的社交應(yīng)用、實(shí)時(shí)分 析引擎,或RESTful API,那么簡單而強(qiáng)大的 ,以及Tornado(和這本書)正是為你準(zhǔn)備的!1.1.1 Tornado入門在大部分*nix系統(tǒng)中安裝Tornado非常容易-你既可以從PyPI獲?。ú⑹褂?easy_install 或 pip 安裝), 也可以從 上 源碼編譯安裝,如下所示1:- 2 -$ curl -L -O/ /tornado/archive/v3.1.0.tar.gz$ tar xvzf v3.1.0.tar

8、.gz$ cd tornado-3.1.0$ setup.py build$ sudo setup.py installTornado 并不支持Windows,但你可以通過Active 的PyPM包管理器進(jìn)行安裝,類似如下所示: C: pypm install tornado一旦Tornado在你的機(jī)器上安裝好,你就可以很好的開始了!壓縮包中包含很多demo,比如建立博客、 整合 、運(yùn)行聊天服務(wù)等的示例代碼。 稍后會(huì)在本書中通過一些示例應(yīng)用逐步講解,不過你也 應(yīng)該看看這些 demo。本 代碼假定你使用的是基于Unix的系統(tǒng),并且使用的是 2.或2.版本。如果是這樣,你就不需要任何除了 標(biāo)準(zhǔn)庫之

9、外的東西。如果你的 版本是2.5或更低,在安裝pycURL、 simpleJSON和 開發(fā)頭文件后可以運(yùn)行Tornado。21.1.2 社區(qū)和支持對于問題、示例和一般的指南,Tornado 文檔是個(gè)不錯(cuò)的選擇。在tornadoweb. 上有大量的例子和功能缺陷, 細(xì)節(jié)和變更可以在Tornado在 上的版本庫中看到。而對于更具體的問題,可以 到Tornado的 Group中咨詢,那里有很多活躍的日常使用Tornado的開發(fā)者。1.2 簡單的Web服務(wù)既然 已經(jīng)知道了Tornado是什么了,現(xiàn)在讓 看看它能做什么吧。 首先從使用Tornado編寫一個(gè)簡單的Web應(yīng)用開始。1.2.1 o Torna

10、doTornado是一個(gè)編寫對HTTP請求響應(yīng)的框架。作為程序員,你的工作是編寫響應(yīng)特定條件HTTP請求的響 應(yīng)的handler。下面是一個(gè)全功能的Tornado應(yīng)用的基礎(chǔ)示例:代碼 1-1 基礎(chǔ): o.py- 3 -import tornado.httpserver import torna oloop import tornado.options import tornado.webfrom tornado.options import define, optionsdefine(port, default=8000, help=run on the given port, type= )

11、class IndexHandler(tornado.web.Reques ndler): def get(self):greeting = self.get_argument(greeting, o) self.write(greeting + , friendly user!)if name = main :tornadomand_line()app = tornado.web.Application(handlers=(r/, IndexHandler)http_server = tornado.httpserver.HTTPServer(app) http_server.listen(

12、options.port)torna oloop.IOLoop.instance().start()編寫一個(gè)Tornado應(yīng)用中最多的工作是定義類繼承Tornado的Reques ndler類。在這個(gè)例子中, 創(chuàng)建了一個(gè)簡單的應(yīng)用,在給定的端口 請求,并在根目錄(/)響應(yīng)請求。你可以在命令行里嘗試運(yùn)行這個(gè)程序以測試輸出:$ o.py -port=8000現(xiàn)在你可以在瀏覽器中打開,或者打開另一個(gè)終端窗口使用curl測試 的應(yīng)用:$ curlo, friendly user!$ curlSalu ions, friendly user!讓 把這個(gè)例子分成小塊,逐步分析它們:import torna

13、do.httpserver import torna oloop import tornado.options import tornado.web在程序的最頂部, 導(dǎo)入了一些Tornado模塊。雖然Tornado還有另外一些有用的模塊,但在這個(gè)例子中 須至少包含這四個(gè)模塊。from tornado.options import define, optionsdefine(port, default=8000, help=run on the given port, type= )- 4 -Tornado包括了一個(gè)有用的模塊(tornado.options)來從命令行中 設(shè)置。 在這里使用這個(gè)

14、模塊指定 的應(yīng)用 HTTP請求的端口。它的工作流程如下:如果一個(gè)與define語句中同名的設(shè)置在命令行中 被給出,那么它將成為全局options的一個(gè)屬性。如果用戶運(yùn)行程序時(shí)使用了 -help 選項(xiàng),程序?qū)⒋蛴〕鏊心愣x的選項(xiàng)以及你在define函數(shù)的help參數(shù)中指定的文本。如果用戶沒有為這個(gè)選項(xiàng)指定值,則使用default的值進(jìn)行代替。Tornado使用type參數(shù)進(jìn)行基本的參數(shù)類型驗(yàn)證,當(dāng)不合適的類型被給出時(shí)拋出一個(gè)異常。因此, 允許一個(gè)整數(shù)的port參數(shù)作為options.port來 程序。如果用戶沒有指定值,則 默認(rèn)為8000。class IndexHandler(tornado.

15、web.Reques ndler): def get(self):greeting = self.get_argument(greeting, o) self.write(greeting + , friendly user!)這是Tornado的請求處理函數(shù)類。當(dāng)處理一個(gè)請求時(shí),Tornado將這個(gè)類實(shí)例化,并調(diào)用與HTTP請求方法所對應(yīng)的方法。在這個(gè)例子中, 只定義了一個(gè)get方法,也就是說這個(gè)處理函數(shù)將對HTTP的GET請求作出響應(yīng)。 稍后將看到實(shí)現(xiàn)不止一個(gè)HTTP方法的處理函數(shù)。greeting = self.get_argument(greeting, o)Tornado的Reque

16、s ndler類有一系列有用的內(nèi)建方法,包括get_argument, 在這里從一個(gè)查詢字符串中取得參數(shù)greeting的值。(如果這個(gè)參數(shù)沒有出現(xiàn)在查詢字符串中,Tornado將使用 get_argument的第二個(gè)參數(shù)作為默認(rèn)值。)self.write(greeting + , friendly user!)Reques ndler的另一個(gè)有用的方法是write,它以一個(gè)字符串作為函數(shù)的參數(shù),并將其寫入到HTTP響應(yīng)中。在這里, 使用請求中g(shù)reeting參數(shù)提供的值 到greeting中,并寫回到響應(yīng)中。if name = main :tornadomand_line()app = to

17、rnado.web.Application(handlers=(r/, IndexHandler)這是真正使得Tornado運(yùn)轉(zhuǎn)起來的語句。首先, 使用Tornado的options模塊來 命令行。然后創(chuàng)建了一個(gè)Tornado的Application類的實(shí)例。傳遞給Application類init方法的最重要的參數(shù)是handlers。它告訴Tornado應(yīng)該用哪個(gè)類來響應(yīng)請求。馬上 講解 相關(guān)知識(shí)。http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port)torna oloop.IOLoop

18、.instance().start()從這里開始的代碼將會(huì)被反復(fù)使用:一旦Application對象被創(chuàng)建, 可以將其傳遞給Tornado的 HTTPServer對象,然后使用 在命令行指定的端口進(jìn)行 (通過options對象取出。)最后,在程序- 5 -準(zhǔn)備好接收HTTP請求后, 創(chuàng)建一個(gè)Tornado的IOLoop的實(shí)例。 參數(shù)handlers讓 再看一眼 o.py示例中的這一行:app = tornado.web.Application(handlers=(r/, IndexHandler)這里的參數(shù)handlers非常重要,值得 更加深入的 。它應(yīng)該是一個(gè)元組組成的列表,其中每個(gè)元組的

19、第一個(gè)元素是一個(gè)用于匹配的正則表達(dá)式,第二個(gè)元素是一個(gè)Reques nlder類。在 o.py中,只指定了一個(gè)正則表達(dá)式-Reques nlder對,但你可以按你的需要指定任意多個(gè)。 使用正則表達(dá)式指定路徑Tornado在元組中使用正則表達(dá)式來匹配HTTP請求的路徑。(這個(gè)路徑是URL中主機(jī)名后面的部分,不包括查詢字符串和碎片。)Tornado把這些正則表達(dá)式看作已經(jīng)包含了行開始和結(jié)束 (即,字符串/被看作為/$)。如果一個(gè)正則表達(dá)式包含一個(gè)捕獲分組(即,正則表達(dá)式中的部分被括號(hào)括起來),匹配的內(nèi)容將作為相應(yīng)HTTP請求的參數(shù)傳到Reques ndler對象中。 在下個(gè)例子中看到它的用法。1.

20、2.2 字符串服務(wù)例1-2是一個(gè) 目前為止看到的更復(fù)雜的例子,它將介紹 Tornado的基本概念。代碼 1-2 處理輸入:string_service.py- -import textwrapimport tornado.httpserver import torna oloop import tornado.options import tornado.webfrom tornado.options import define, optionsdefine(port, default=8000, help=run on the given port, type= )class Reverse

21、Handler(tornado.web.Reques ndler): def get(self, input):self.write(input:-1)class WrapHandler(tornado.web.Reques ndler): def t(self):text = self.get_argument(text)width = self.get_argument(width, 40) self.write(textwrap.fill(text, (width)if name = main :tornadomand_line()app = tornado.web.Applicatio

22、n(handlers=(r/reverse/(w+), ReverseHandler), (r/wrap, WrapHandler)http_server = tornado.httpserver.HTTPServer(app)http_server.listen(options.port)torna oloop.IOLoop.instance().start()如同運(yùn)行第一個(gè)例子,你可以在命令行中運(yùn)行這個(gè)例子使用如下 令:$ string_service.py -port=8000這個(gè)程序是一個(gè)通用的字符串操作的Web服務(wù)端基本框架。到目前為止,你可以用它做兩件事情。其一,到 /revers

23、e/string 的GET請求將會(huì)返回URL路徑中指定字符串的反轉(zhuǎn)形式。$ curl desserts$ curl pupils其二,到 /wrap 的 T請求將從參數(shù)text中取得指定的文本,并返回按照參數(shù)width指定寬度裝飾的文 本。下面的請求指定一個(gè)沒有寬度的字符串,所以它的輸出寬度被指定為程序中的get_argument的默認(rèn)值 40個(gè)字符。- -$-d text=Lorem+ipsum+dolor+sit+amet,+consectetuer+adipiscing+elit.Lorem ipsum dolor sit amet, consectetueradipiscing eli

24、t.字符串服務(wù)示例和上一節(jié)示例代碼中大部分是一樣的。讓 關(guān)注那些新的代碼。首先,讓 看看傳遞給Application構(gòu)造函數(shù)的handlers參數(shù)的值:app = tornado.web.Application(handlers= (r/reverse/(w+), ReverseHandler), (r/wrap, WrapHandler)在上面的代碼中,Application類在handlers參數(shù)中實(shí)例化了兩個(gè)Reques ndler類對象。第一個(gè)引導(dǎo) Tornado傳遞路徑匹配下面的正則表達(dá)式的請求:/reverse/(w+)正則表達(dá)式告訴Tornado匹配任何以字符串/reverse/

25、開始并緊跟著一個(gè)或多個(gè)字母的路徑。括號(hào)的含義是讓Tornado保存匹配括號(hào)里面表達(dá)式的字符串,并將其作為請求方法的一個(gè)參數(shù)傳遞給Reques ndler 類。讓 檢查ReverseHandler的定義來看看它是如何工作的:class ReverseHandler(tornado.web.Reques ndler): def get(self, input):self.write(input:-1)你可以看到這里的get方法有一個(gè)額外的參數(shù)input。這個(gè)參數(shù)將包含匹配處理函數(shù)正則表達(dá)式第一個(gè)括號(hào)里的字符串。(如果正則表達(dá)式中有一系列額外的括號(hào),匹配的字符串將被按照在正則表達(dá)式中出現(xiàn)的順序作為額

26、外的參數(shù)傳遞進(jìn)來。)現(xiàn)在,讓 看一下WrapHandler的定義:class WrapHandler(tornado.web.Reques ndler): def t(self):text = self.get_argument(text)width = self.get_argument(width, 40) self.write(textwrap.fill(text, (width)WrapHandler類處理匹配路徑為 /wrap 的請求。這個(gè)處理函數(shù)定義了一個(gè) t方法,也就是說它接收 HTTP的 T方法的請求。之前使用Reques ndler對象的get_argument方法來捕獲請求

27、查詢字符串的的參數(shù)。同樣, 也可以使用相同的方法來獲得 T請求傳遞的參數(shù)。(Tornado可以 URLencoded和multipart結(jié)構(gòu)的T請求)。一旦 從 T中獲得了文本和寬度的參數(shù), 使用 內(nèi)建的textwrap模塊來以- 8 -指定的寬度裝飾文本,并將結(jié)果字符串寫回到HTTP響應(yīng)中。關(guān)于Reques ndler的 知識(shí)到目前為止, 已經(jīng)了解了Reques ndler對象的基礎(chǔ):如何從一個(gè)傳入的HTTP請求中獲得信息(使 用get_argument和傳入到get和 t的參數(shù))以及寫HTTP響應(yīng)(使用write方法)。除此之外,還有很多 需要學(xué)習(xí)的, 在接下來的章節(jié)中進(jìn)行講解。同時(shí),還有

28、一些關(guān)于Reques ndler和Tornado如何使用它的只是需要記住。HTTP方法截止到目前 的例子,每個(gè)Reques ndler類都只定義了一個(gè)HTTP方法的行為。但是,在同一個(gè)處理函數(shù)中定義多個(gè)方法是可能的,并且是有用的。把概念相關(guān)的功能綁定到同一個(gè)類是一個(gè)很好的方法。比如,你可能會(huì)編寫一個(gè)處理函數(shù)來處理數(shù)據(jù)庫中某個(gè)特定ID的對象,既使用GET方法,也使用 T方法。想象GET方法來返回這個(gè)部件的信息,而 T方法在數(shù)據(jù)庫中對這個(gè)ID的部件進(jìn)行改變:# matched with (r/widget/(d+), Widge ndler) class Widge ndler(tornado.w

29、eb.Reques ndler):def get(self, widget_id):widget = retrieve_from_db(widget_id) self.write(widget.serialize()def t(self, widget_id):widget = retrieve_from_db(widget_id) widgetfoo = self.get_argument(foo) save_to_db(widget)到目前為止只是用了GET和 T方法,但Tornado支持任何合法的HTTP請求(GET、 T、PUT、 DELETE、HEAD、OPTIONS)。你可以非常容

30、易地定義上述任 法的行為,只需要在Reques ndler類中使用同名的方法。下面是另一個(gè) 例子,在這個(gè)例子中針對特定frob ID的 HEAD請求只根據(jù)frob是否存在給出信息,而GET方法返回整個(gè)對象:# matched with (r/frob/(d+), FrobHandler) class FrobHandler(tornado.web.Reques ndler):def head(self, frob_id):frob = retrieve_from_db(frob_id) if frob is not None:self.set_s us(200) else:self.set_s

31、 us(404) def get(self, frob_id):frob = retrieve_from_db(frob_id) self.write(frob.serialize() HTTP狀態(tài)碼從上面的代碼可以看出,你可以使用Reques ndler類的ser_s us()方法顯式地設(shè)置HTTP狀態(tài)碼。然- 9 -而,你需要記住在某些情況下,Tornado會(huì)自動(dòng)地設(shè)置HTTP狀態(tài)碼。下面是一個(gè)常用情況的綱要: 404 Not FoundTornado會(huì)在HTTP請求的路徑無法匹配任何Reques ndler類相對應(yīng)的模式時(shí)返回404(Not Found)響應(yīng)碼。400 Bad Reque

32、st如果你調(diào)用了一個(gè)沒有默認(rèn)值的get_argument函數(shù),并且沒有發(fā)現(xiàn)給定名稱的參數(shù),Tornado將自動(dòng)返回一個(gè)400(Bad Request)響應(yīng)碼。405 Method Not Allowed如果傳入的請求使用了Reques ndler中沒有定義的HTTP方法(比如,一個(gè) T請求,但是處理函數(shù)中只有定義了get方法),Tornado將返回一個(gè)405(Methos Not Allowed)響應(yīng)碼。500 ernal Server Error當(dāng)程序遇到任何不能讓其退出的錯(cuò)誤時(shí),Tornado將返回500( ernal Server Error)響應(yīng)碼。你代碼中任何沒有捕獲的異常也會(huì)導(dǎo)致5

33、00響應(yīng)碼。200 OK如果響應(yīng)成功,并且沒有其他返回碼被設(shè)置,Tornado將默認(rèn)返回一個(gè)200(OK)響應(yīng)碼。當(dāng)上述任何一種錯(cuò)誤發(fā)生時(shí),Tornado將默認(rèn)向客戶端發(fā)送一個(gè)包含狀態(tài)碼和錯(cuò)誤信息的簡短片段。如果你想使用自己的方法代替默認(rèn)的錯(cuò)誤響應(yīng),你可以重寫write_error方法在你的Reques ndler類中。比如,代碼 1-3是 o.py示例添加了常規(guī)的錯(cuò)誤消息的版本。代碼 1-3 常規(guī)錯(cuò)誤響應(yīng): o-errors.py- 10 -import tornado.httpserver import torna oloop import tornado.options import t

34、ornado.webfrom tornado.options import define, optionsdefine(port, default=8000, help=run on the given port, type= )class IndexHandler(tornado.web.Reques ndler):def get(self):greeting = self.get_argument(greeting, o) self.write(greeting + , friendly user!)def write_error(self, s us_code, *kwargs):sel

35、f.write(Gosh darnit, user! You caused a %d error. % s us_code)if name = main :tornadomand_line()app = tornado.web.Application(handlers=(r/, IndexHandler)http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port)torna oloop.IOLoop.instance().start()當(dāng) 嘗試一個(gè) T請求時(shí),會(huì)得到下面的響應(yīng)。一般來說, 應(yīng)該

36、得到Tornado默認(rèn)的錯(cuò)誤響應(yīng),但因?yàn)?覆寫了write_error, 會(huì)得到不一樣的東西:$ curl -d foo=barGosh darnit, user! You caused a 405 error.1.2.4 下一步現(xiàn)在你已經(jīng)明白了最基本的東西, 渴望你想了解 。在接下來的章節(jié), 向你展示能夠幫助你使用Tornado創(chuàng)建成 Web服務(wù)和應(yīng)用的功能和技術(shù)。首先是:Tornado的模板系統(tǒng)。壓縮包地址已更新到Tornado的最新版本3.1.0。書中原文中關(guān)于 3.X版本的兼容性問題目前已不存在,因此省略該部分。- 11 -第二章:表單和模板在第一章中,學(xué)習(xí)了使用Tornado創(chuàng)建一個(gè)

37、Web應(yīng)用的基礎(chǔ)知識(shí)。包括處理函數(shù)、HTTP方法以及Tornado框架的總體結(jié)構(gòu)。在這章中,學(xué)些你在創(chuàng)建Web應(yīng)用時(shí)經(jīng)常會(huì)用到的更強(qiáng)大的功能。和大多數(shù)Web框架一樣,Tornado的一個(gè)重要目標(biāo)就是幫助你更快地編寫程序,盡可能整潔地復(fù)用的代碼。盡管Tornado足夠靈活,可以使用幾乎所有支持的模板語言,Tornado自身也提供了一個(gè)輕量級(jí)、快速并且靈活的模板語言在tornado.template模塊中。簡單示例:Poem Mak渲染模板填充ro模板語法填充表達(dá)式控制流語句在模板中使用函數(shù)復(fù)雜示例:The Alpha Munger它如何工作提供靜態(tài)文件模板的下一步2.1 簡單示例:Poem Ma

38、k讓以一個(gè)叫作Poem Makro的簡單例子開始。Poem Makro這個(gè)Web應(yīng)用有一個(gè)讓用戶填寫的HTML表單,然后處理表單的結(jié)果。代碼2-1是它的代碼。代碼2-1 簡單表單和模板:poemmaky- 12 -import os.pathimport tornado.httpserverimport tornaoloopimport tornado.options import tornado.webfrom tornado.options import define, optionsdefine(port, default=8000, help=run on the given port

39、, type=)class IndexHandler(tornado.web.Reques def get(self):self.render(index.html)ndler):class PoemPageHandler(tornado.web.Requesndler):deft(self):noun1 = self.get_argument(noun1) noun2 = self.get_argument(noun2) verb = self.get_argument(verb)noun3 = self.get_argument(noun3)self.render(poem.html, r

40、oads=noun1, wood=noun2, made=verb, difference=noun3)if name = main : tornadomand_line()app = tornado.web.Application(handlers=(r/, IndexHandler), (r/poem, PoemPageHandler), template_path=os.path.join(os.path.dirname( file ), templates)http_server = tornado.httpserver.HTTPServer(app)http_server.liste

41、n(options.port)tornaoloop.IOLoop.instance().start()除了poemmak中。y,你還需要將代碼2-2和代碼2-3中的兩個(gè)文件加入到templates子文件夾代碼2-2 Poem Maker表單:index.html- 13 -Poem MakroEnter terms below.Plural nounSingular nounVerb (past tense)Noun代碼2-3 Poem Maker模板:poem.htmlPoem MakYour poemroTwo roads diverged in a wood, and II took t

42、he one less travelled by,Ands made all the difference.在命令行執(zhí)行下述命令:$poemmaky -port=8000現(xiàn)在,在瀏覽器中打開。當(dāng)瀏覽器請求根目錄(/)時(shí),Tornado程序?qū)秩緄ndex.html,展示如圖2-1所示的簡單HTML表單。- 14 -圖2-1 Poem Makro:輸入表單這個(gè)表單包括多個(gè)文本域(命名為noun1、noun2等),其中的內(nèi)容將在用戶點(diǎn)擊Submit按鈕時(shí)以T請求的方式送到 /poem ?,F(xiàn)在往里面填寫東西然后點(diǎn)擊提交吧。為了響應(yīng)這個(gè)T請求,Tornado應(yīng)用跳轉(zhuǎn)到poem.html,你在表單中填寫

43、的值。結(jié)果是RobertFrost的詩The Road Not Taken的輕微修本。圖2-2展示了這個(gè)結(jié)果。- 15 -圖2-2 Poem Makro:輸出2.1.1 渲染模板從結(jié)構(gòu)上講,poemmaky和第一章中的例子很相似。定義了幾個(gè)Requesndler子類并把它們傳給tornado.web.Application對象。那么有什么不一樣的地方呢?首先,法傳遞了一個(gè)template_path參數(shù)。向Application對象的init方template_path=os.path.join(os.path.dirname( file ), templates)template_path參數(shù)

44、告訴Tornado在哪里尋找模板文件。在本章和第三章中講解其確切性質(zhì)和語法,而它的基本要點(diǎn)是:模板是一個(gè)允許你嵌入代碼片段的HTML文件。上面的代碼告訴在你Tornado應(yīng)用文件同目錄下的templates文件夾中尋找模板文件。一旦告訴Tornado在哪里找到模板,可以使用Requesndler類的render方法來告訴Tornado讀入模板文件,的語句:其中的模版代碼,并返回結(jié)果給瀏覽器。比如,在IndexHandler中,發(fā)現(xiàn)了下面self.render(index.html)這段代碼告訴Tornado在templates文件夾下找到一個(gè)名為index.html的文件,送給瀏覽器。其中的內(nèi)

45、容,并且發(fā)2.1.2 填充- 1 -在這里, 告訴模板使用變量noun1(該變量是從get_argument方法取得的)作為模板中roads的值,noun2作為模板中wood的值,依此類推。假設(shè)用戶在表單中按順序鍵入了pineapples、grandfather clock、irradiated和supernovae,那么結(jié)果HTML將會(huì)如下所示:2.2 模板語法既然 已經(jīng)看到了一個(gè)模板在實(shí)際應(yīng)用中的簡單例子,那么讓 深入地了解它們是如何工作的吧。 Tornado模板是被 表達(dá)式和控制語句標(biāo)記的簡單文本文件。Tornado的語法非常簡單直接。熟悉 Django、Liquid或其他相似框架的用戶

46、會(huì)發(fā)現(xiàn)它們非常相似,很容易學(xué)會(huì)。在2.1節(jié)中, 展示了如何在一個(gè)Web應(yīng)用中使用render方法傳送HTML給瀏覽器。你可以在Tornado應(yīng) 用之外使用 解釋器導(dǎo)入模板模塊嘗試模板系統(tǒng),此時(shí)結(jié)果會(huì)被直接輸出出來。- 1 - from tornado.template import Template content = Template( header ) pr content.generate(header= e!) e!Two pineapples diverged in a grandfather clock, and I I took the one less travelled by

47、,And s irradiated all the supernovae.2.2.1 填充表達(dá)式在代碼 2-1中, 演示了填充 變量的值到模板的雙大括號(hào)中的使用。實(shí)際上,你可以將任何 表達(dá)式放在雙大括號(hào)中。Tornado將 一個(gè)包含任何表達(dá)式計(jì)算結(jié)果值的字符串到輸出中。下面是幾個(gè)可能的例子:2.2.2 控制流語句你同樣可以在Tornado模板中使用 條件和循環(huán)語句??刂普Z句以%和%包圍,并以類似下面的形式被使用: % if page is None %或 % if len(entries) = 3 %控制語句的大部分就像對應(yīng)的 語句一樣工作,支持if、for、while和try。在這些情況下,

48、語句塊以%開始,并以%結(jié)束。所以這個(gè)模板:當(dāng)被下面這個(gè)處理函數(shù)調(diào)用時(shí):- 18 - title header % for book in books % book % end % from tornado.template import Template pr2 pr eggs prTemplate( 1+1 ).generate()Template( scrambled eggs-4: ).generate()Template( , .join(str(x*x) for x in range(10) ).generate()0, 1, 4, 9, 1, 25, 3, 49, 4, 81將會(huì)渲

49、染得到下面的輸出:Home PageBooks t are greatLearning Programming Collective elligenceRestful Web Servi 不像許多其他的 模板系統(tǒng),Tornado模板語言的一個(gè)最好的東西是在if和for語句塊中可以使用的表 達(dá)式?jīng)]有限制。因此,你可以在你的模板中執(zhí)行所有的 代碼。同樣,你也可以在你的控制語句塊中間使用 % set foo = bar % 來設(shè)置變量。你還有很多可以在控制語句塊中做的事情,但是在大多數(shù)情況下,你最好使用UI模塊來做更復(fù)雜的劃分。 稍后會(huì)更詳細(xì)的看到 這一點(diǎn)。2.2.3 在模板中使用函數(shù)Tornado

50、在所有模板中默認(rèn)提供了一些便利的函數(shù)。它們包括:esc (s)替換字符串s中的&、為他們對應(yīng)的HTML字符。 url_esc (s)使用urllib.quote_plus替換字符串s中的字符為URL編碼形式。json_encode(val)- 19 -class BookHandler(tornado.web.Reques ndler): def get(self):self.render( book.html, title=Home Page,header=Books t are great,books=Learning ,Programming Collective elligence,

51、Restful Web Servi )將val編碼成JSON格式。(在系統(tǒng)底層,這是一個(gè)對json庫的dumps函數(shù)的調(diào)用。查閱相關(guān)的文檔以獲得關(guān)于該函數(shù)接收和返回參數(shù)的信息。)squeeze(s)過濾字符串s,把連續(xù)的多個(gè)空白字符替換成一個(gè)空格。在Tornado 1.x中,模版不是被自動(dòng)轉(zhuǎn)義的。在Tornado 2.0中,模板被默認(rèn)為自動(dòng)轉(zhuǎn)義(并且可以在 Application構(gòu)造函數(shù)中使用autosca =None關(guān)閉)。在不同版本的遷移時(shí)要注意向后兼容。在模板中使用一個(gè)你自己編寫的函數(shù)也是很簡單的:只需要將函數(shù)名作為模板的參數(shù)傳遞即可,就像其他 變量一樣。2.3 復(fù)雜示例:The Alp

52、ha Munger在代碼 2-4中, 把在這一章中談?wù)撨^的所有東西都放了進(jìn)來。這個(gè)應(yīng)用被稱為The Alpha Munger。用戶輸入兩個(gè)文本:一個(gè)源文本和一個(gè)替代文本。應(yīng)用會(huì)返回替代文本的一個(gè)副本,并將其 中每個(gè)單詞替換成源文本中首字母相同的某個(gè)單詞。圖2-3展示了要填的表單,圖2-4展示了結(jié)果文本。這個(gè)應(yīng)用包括四個(gè)文件:main.py(Tornado程序)、style.css(CSS樣式表文件)、index.html和 munged.html(Tornado模板)。讓 看看代碼吧:代碼 2-4 復(fù)雜表單和模板:main.py- 20 - from tornado.template impo

53、rt Template def disemvowel(s):. return .join(x for x in s if x not in aeiou). disemvowel(ge e) grg pr Template(my name is d(mortimer).generate(d=disemvowel) my name is mrtmrimport os.path import randomimport tornado.httpserver import torna oloop import tornado.options import tornado.webfrom tornado.

54、options import define, optionsdefine(port, default=8000, help=run on the given port, type= )class IndexHandler(tornado.web.Reques ndler): def get(self):self.render(index.html)class MungedPageHandler(tornado.web.Reques ndler):def map_by_ _letter(self, text):mapped = dict()for line ext.split(rn):for w

55、ord in x for x in line.split( ) if len(x) 0:if word0 not apped: mappedword0 = mappedword0.append(word)return mappeddef t(self):source_text = self.get_argument(source) text_to_change = self.get_argument(change) source_map = self.map_by_ _letter(source_text) change_lines = text_to_change.split(rn)self

56、.render(munged.html, source_map=source_map, change_lines=change_lines, choice=random.choice)if name = main :tornadomand_line() app = tornado.web.Application(handlers=(r/, IndexHandler), (r/poem, MungedPageHandler), template_path=os.path.join(os.path.dirname( file ), templates), s ic_path=os.path.joi

57、n(os.path.dirname( file ), s ic), debug=True)http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port)torna oloop.IOLoop.instance().start()- 21 -圖2-3 Alpha Munger:輸入表單- 22 -圖2-4 Alpha Munger:輸出記住Application構(gòu)造函數(shù)中的s就是sic_path參數(shù)。另外,你還需要在templates文件夾下添加index.html和munged.htm件。代碼-

58、23 -link rel=stylesheet href= sThe Alpha MungerThe Alpha Mungeric_url(style.css) Enter two texts below. The replacement text will replaced by words beginning with the same lettere its wordshe source text.Source textText for replacement代碼2- Alpha Munger模板:munged.htmllink rel=stylesheet href= sThe Alp

59、ha MungerYour text% for line in change_lines % for word in line.split( ) %ic_url(style.css) % if len(word) 0 and word0 in source_map % choi% else %ource_mapword0) word% end % end % end %最后,將代碼2-中的內(nèi)容寫到sic子目錄下的style.css文件中。代碼2- Alpha Munger樣式表:style.css- 24 -body font-family: Helvetica,Arial,sans-seri

60、f; width: 00px;margin: 0 auto;.replaced:hover color: #00f; 2.3.1 它如何工作這個(gè)Tornado應(yīng)用定義了兩個(gè)請求處理類:IndexHandler和MungedPageHandler。IndexHandler類簡單地渲染了index.html中的模板,其中包括一個(gè)允許用戶文本(在change域中)到 /poem 的表單。T一個(gè)源文本(在source域中)和一個(gè)替換MungedPageHandler類用于處理到 /poem 的基本的處理,然后為瀏覽器渲染模板。map_by_T請求。當(dāng)一個(gè)請求到達(dá)時(shí),它對傳入的數(shù)據(jù)進(jìn)行一些_letter

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論