成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Tornado 4.3文檔翻譯: 用戶指南-web應(yīng)用的結(jié)構(gòu)

LinkedME2016 / 2611人閱讀

摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。

譯者說

Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5async/await關(guān)鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持Python2.6Python3.2的版本了,在后續(xù)的版本了會移除對它們的兼容?,F(xiàn)在網(wǎng)絡(luò)上還沒有Tornado4.3的中文文檔,所以為了讓更多的朋友能接觸并學習到它,我開始了這個翻譯項目,希望感興趣的小伙伴可以一起參與翻譯,項目地址是tornado-zh on Github,翻譯好的文檔在Read the Docs上直接可以看到。歡迎Issues or PR。

Tornado web應(yīng)用的結(jié)構(gòu)

通常一個Tornado web應(yīng)用包括一個或者多個RequestHandler 子類,一個可以將收到的請求路由到對應(yīng)handler的Application 對象,和一個啟動服務(wù)的 main() 函數(shù).

一個最小的"hello world"例子就像下面這樣:

    import tornado.ioloop
    import tornado.web

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")

    def make_app():
        return tornado.web.Application([
            (r"/", MainHandler),
        ])

    if __name__ == "__main__":
        app = make_app()
        app.listen(8888)
        tornado.ioloop.IOLoop.current().start()
Application 對象

Application對象是負責全局配置的,包括映射請求轉(zhuǎn)發(fā)給處理程序的路由表.

路由表是URLSpec對象(或元組)的列表, 其中每個都包含(至少)一個正則表達式和一個處理類. 順序問題; 第一個匹配的規(guī)則會被使用. 如果正則表達式包含捕獲組, 這些組會被作為 路徑參數(shù) 傳遞給處理函數(shù)的HTTP方法.如果一個字典作為 URLSpec 的第三個參數(shù)被傳遞, 它會作為 初始參數(shù)傳遞給 RequestHandler.initialize. 最后 URLSpec 可能有一個名字(name), 這將允許它被 RequestHandler.reverse_url 使用.

例如, 在這個片段中根URL / 映射到了MainHandler , 像 /story/ 后跟著一個數(shù)字這種形式的URL被映射到了StoryHandler. 這個數(shù)字被傳遞(作為字符串)給StoryHandler.get.

    class MainHandler(RequestHandler):
        def get(self):
            self.write("link to story 1" %
                       self.reverse_url("story", "1"))

    class StoryHandler(RequestHandler):
        def initialize(self, db):
            self.db = db

        def get(self, story_id):
            self.write("this is story %s" % story_id)

    app = Application([
        url(r"/", MainHandler),
        url(r"/story/([0-9]+)", StoryHandler, dict(db=db), name="story")
        ])

Application 構(gòu)造函數(shù)有很多關(guān)鍵字參數(shù)可以用于自定義應(yīng)用程序的行為和使用某些特性(或者功能); 完整列表請查看Application.settings .

RequestHandler 子類

Tornado web 應(yīng)用程序的大部分工作是在RequestHandler子類下完成的.處理子類的主入口點是一個命名為處理HTTP方法的函數(shù): get(),post(), 等等. 每個處理程序可以定義一個或者多個這種方法來處理不同的HTTP動作. 如上所述, 這些方法將被匹配路由規(guī)則的捕獲組對應(yīng)的參數(shù)調(diào)用.

在處理程序中, 調(diào)用方法如RequestHandler.render 或者RequestHandler.write 產(chǎn)生一個響應(yīng). render() 通過名字加載一個Template 并使用給定的參數(shù)渲染它. write() 被用于非模板基礎(chǔ)的輸出; 它接受字符串, 字節(jié), 和字典(字典會被編碼成JSON).

RequestHandler 中的很多方法的設(shè)計是為了在子類中復寫和在整個應(yīng)用中使用. 常用的方法是定義一個 BaseHandler 類, 復寫一些方法例如RequestHandler.write_errorRequestHandler.get_current_user然后子類繼承使用你自己的 BaseHandler 而不是RequestHandler在你所有具體的處理程序中.

處理輸入請求

處理請求的程序(request handler)可以使用 self.request 訪問代表當前請求的對象. 通過tornado.httputil.HTTPServerRequest 的類定義查看完整的屬性列表.

使用HTML表單格式請求的數(shù)據(jù)會被解析并且可以在一些方法中使用, 例如RequestHandler.get_query_argumentRequestHandler.get_body_argument.

    class MyFormHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("
" "" "" "
") def post(self): self.set_header("Content-Type", "text/plain") self.write("You wrote " + self.get_body_argument("message"))

由于HTLM表單編碼不確定一個標簽的參數(shù)是單一值還是一個列表,RequestHandler 有明確的方法來允許應(yīng)用程序表明是否它期望接收一個列表.對于列表, 使用RequestHandler.get_query_argumentsRequestHandler.get_body_arguments 而不是它們的單數(shù)形式.

通過一個表單上傳的文件可以使用 self.request.files,它遍歷名字(HTML 標簽 的name)到一個文件列表.每個文件都是一個字典的形式{"filename":..., "content_type":..., "body":...}. files對象是當前唯一的如果文件上傳是通過一個表單包裝(i.e. a multipart/form-data Content-Type); 如果沒用這種格式,原生上傳的數(shù)據(jù)可以調(diào)用 self.request.body 使用.默認上傳的文件是完全緩存在內(nèi)存中的; 如果你需要處理占用內(nèi)存太大的文件可以看看 stream_request_body 類裝飾器.

由于HTML表單編碼格式的怪異 (e.g. 在單數(shù)和復數(shù)參數(shù)的含糊不清), Tornado不會試圖統(tǒng)一表單參數(shù)和其他輸入類型的參數(shù). 特別是, 我們不解析JSON請求體.應(yīng)用程序希望使用JSON代替表單編碼可以復寫 RequestHandler.prepare來解析它們的請求:

    def prepare(self):
        if self.request.headers["Content-Type"].startswith("application/json"):
            self.json_args = json.loads(self.request.body)
        else:
            self.json_args = None
復寫RequestHandler的方法

除了 get()/post()/等, 在 .RequestHandler 中的某些其他方法被設(shè)計成了在必要的時候讓子類重寫. 在每個請求中, 會發(fā)生下面的調(diào)用序列:

在每次請求時生成一個新的 RequestHandler 對象

RequestHandler.initialize()Application 配置中的初始化參數(shù)被調(diào)用. initialize 通常應(yīng)該只保存成員變量傳遞的參數(shù); 它不可能產(chǎn)生任何輸出或者調(diào)用方法, 例如RequestHandler.send_error.

RequestHandler.prepare() 被調(diào)用. 這在你所有處理子類共享的基類中是最有用的, 無論是使用哪種HTTP方法, prepare 都會被調(diào)用.prepare 可能會產(chǎn)生輸出; 如果它調(diào)用 RequestHandler.finish(或者 redirect, 等), 處理會在這里結(jié)束.

其中一種HTTP方法被調(diào)用: get(), post(), put(),等. 如果URL的正則表達式包含捕獲組, 它們會被作為參數(shù)傳遞給這個方法.

當請求結(jié)束, RequestHandler.on_finish() 方法被調(diào)用. 對于同步處理程序會在 get() (等)后立即返回; 對于異步處理程序,會在調(diào)用RequestHandler.finish() 后返回.

所有這樣設(shè)計被用來復寫的方法被記錄在了RequestHandler的文檔中.其中最常用的一些被復寫的方法包括:

RequestHandler.write_error - 輸出對錯誤頁面使用的HTML.

RequestHandler.on_connection_close - 當客戶端斷開時被調(diào)用;應(yīng)用程序可以檢測這種情況,并中斷后續(xù)處理. 注意這不能保證一個關(guān)閉的連接及時被發(fā)現(xiàn).

RequestHandler.get_current_user - 參考 user-authentication

RequestHandler.get_user_locale - 返回 .Locale 對象給當前
用戶使用

RequestHandler.set_default_headers - 可以被用來設(shè)置額外的響應(yīng)
頭(例如自定義的 Server 頭)

錯誤處理

如果一個處理程序拋出一個異常, Tornado會調(diào)用RequestHandler.write_error 來生成一個錯誤頁.tornado.web.HTTPError 可以被用來生成一個指定的狀態(tài)碼; 所有其他的異常都會返回一個500狀態(tài).

默認的錯誤頁面包含一個debug模式下的調(diào)用棧和另外一行錯誤描述(e.g. "500: Internal Server Error"). 為了創(chuàng)建自定義的錯誤頁面, 復寫RequestHandler.write_error (可能在一個所有處理程序共享的一個基類里面).這個方法可能產(chǎn)生輸出通常通過一些方法, 例如 RequestHandler.writeRequestHandler.render. 如果錯誤是由異常引起的, 一個 exc_info 將作為一個關(guān)鍵字參數(shù)傳遞(注意這個異常不能保證是 sys.exc_info 當前的異常, 所以 write_error 必須使用 e.g. traceback.format_exception 代替traceback.format_exc).

也可以在常規(guī)的處理方法中調(diào)用 RequestHandler.set_status 代替write_error 返回一個(自定義)響應(yīng)來生成一個錯誤頁面. 特殊的例外tornado.web.Finish 在直接返回不方便的情況下能夠在不調(diào)用 write_error前結(jié)束處理程序.

對于404錯誤, 使用 default_handler_class Application setting. 這個處理程序會復寫RequestHandler.prepare 而不是一個更具體的方法, 例如 get()所以它可以在任何HTTP方法下工作. 它應(yīng)該會產(chǎn)生如上所說的錯誤頁面: 要么raise一個 HTTPError(404) 要么復寫 write_error, 或者調(diào)用self.set_status(404) 或者在 prepare() 中直接生成響應(yīng).

重定向

這里有兩種主要的方式讓你可以在Tornado中重定向請求:RequestHandler.redirect 和使用 RedirectHandler.

你可以在一個 RequestHandler 的方法中使用 self.redirect() 把用戶重定向到其他地方. 還有一個可選參數(shù) permanent 你可以使用它來表明這個重定向被認為是永久的. permanent 的默認值是 False, 這會生成一個302 Found HTTP響應(yīng)狀態(tài)碼, 適合類似在用戶的 POST 請求成功后的重定向.如果 permanent 是true, 會使用 301 Moved Permanently HTTP響應(yīng), 更適合e.g. 在SEO友好的方法中把一個頁面重定向到一個權(quán)威的URL.

RedirectHandler 讓你直接在你 Application 路由表中配置. 例如, 配置一個靜態(tài)重定向:

    app = tornado.web.Application([
        url(r"/app", tornado.web.RedirectHandler,
            dict(url="http://itunes.apple.com/my-app-id")),
        ])

RedirectHandler 也支持正則表達式替換. 下面的規(guī)則重定向所有以 /pictures/開始的請求用 /photos/ 前綴代替:

    app = tornado.web.Application([
        url(r"/photos/(.*)", MyPhotoHandler),
        url(r"/pictures/(.*)", tornado.web.RedirectHandler,
            dict(url=r"/photos/1")),
        ])

不像 RequestHandler.redirect, RedirectHandler 默認使用永久重定向.這是因為路由表在運行時不會改變, 而且被認為是永久的.當在處理程序中發(fā)現(xiàn)重定向的時候, 可能是其他可能改變的邏輯的結(jié)果.用 .RedirectHandler 發(fā)送臨時重定向, 需要添加 permanent=False.RedirectHandler 的初始化參數(shù).

異步處理

Tornado默認會同步處理: 當 get()/post() 方法返回, 請求被認為結(jié)束并且返回響應(yīng). 因為當一個處理程序正在運行的時候其他所有請求都被阻塞,任何需要長時間運行的處理都應(yīng)該是異步的, 這樣它就可以在非阻塞的方式中調(diào)用它的慢操作了. 這個話題更詳細的內(nèi)容包含在async 中; 這部分是關(guān)于在 RequestHandler 子類中的異步技術(shù)的細節(jié).

使用 coroutine 裝飾器是做異步最簡單的方式. 這允許你使用 yield 關(guān)鍵字執(zhí)行非阻塞I/O, 并且直到協(xié)程返回才發(fā)送響應(yīng). 查看 coroutines了解更多細節(jié).

在某些情況下, 協(xié)程不如回調(diào)為主的風格方便, 在這種情況下tornado.web.asynchronous 裝飾器可以用來代替. 當使用這個裝飾器的時候,響應(yīng)不會自動發(fā)送; 而請求將一直保持開放直到callback調(diào)用RequestHandler.finish. 這需要應(yīng)用程序確保這個方法被調(diào)用或者其他用戶的瀏覽器簡單的掛起.

這里是一個使用Tornado"s 內(nèi)置的 AsyncHTTPClient 調(diào)用FriendFeed API的例
子:

    class MainHandler(tornado.web.RequestHandler):
        @tornado.web.asynchronous
        def get(self):
            http = tornado.httpclient.AsyncHTTPClient()
            http.fetch("http://friendfeed-api.com/v2/feed/bret",
                       callback=self.on_response)

        def on_response(self, response):
            if response.error: raise tornado.web.HTTPError(500)
            json = tornado.escape.json_decode(response.body)
            self.write("Fetched " + str(len(json["entries"])) + " entries "
                       "from the FriendFeed API")
            self.finish()

get() 返回, 請求還沒有完成. 當HTTP客戶端最終調(diào)用on_response(), 這個請求仍然是開放的, 響應(yīng)最終刷到客戶端通過調(diào)用 self.finish().

為了方便對比, 這里有一個使用協(xié)程的相同的例子:

    class MainHandler(tornado.web.RequestHandler):
        @tornado.gen.coroutine
        def get(self):
            http = tornado.httpclient.AsyncHTTPClient()
            response = yield http.fetch("http://friendfeed-api.com/v2/feed/bret")
            json = tornado.escape.json_decode(response.body)
            self.write("Fetched " + str(len(json["entries"])) + " entries "
                       "from the FriendFeed API")

更多高級異步的示例, 請看chat example application, 實現(xiàn)了一個使用 長輪詢(long polling)的AJAX聊天室.使用長輪詢的用戶可能想要覆蓋 on_connection_close() 來在客戶端關(guān)閉連接之后進行清理(注意看方法的文檔來查看警告).

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/37705.html

相關(guān)文章

  • Tornado 4.3文檔翻譯: 用戶指南-介紹

    摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。 譯者說 Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次...

    chaos_G 評論0 收藏0
  • Tornado 4.3文檔翻譯: 用戶指南-介紹

    摘要:譯者說于年月日發(fā)布,該版本正式支持的關(guān)鍵字,并且用舊版本編譯同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次,這是最后一個支持和的版本了,在后續(xù)的版本了會移除對它們的兼容。 譯者說 Tornado 4.3于2015年11月6日發(fā)布,該版本正式支持Python3.5的async/await關(guān)鍵字,并且用舊版本CPython編譯Tornado同樣可以使用這兩個關(guān)鍵字,這無疑是一種進步。其次...

    xumenger 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<