tornado之HelloWorld

tornado是python的一個輕量級的web框架,主要特點是非阻塞式的,處理速度快,而且是輕量級的,使用方便。反之Django則是一個重量級的大而全的框架,功能較多,生態較全。


HelloWorld

直接看最簡單的demo:

import tornado.ioloop
import tornado.web

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

if __name__ == "__main__":
	application = tornado.web.Application([(r"/", MainHandler)])
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

啓動後(注意,文件名不要用tornado命名),在地址欄輸入localhost:8888/test即可看到輸出:
在這裏插入圖片描述
分析一下這個簡單的demo:
首先,生成一個Apptioncation實例,在構造函數中傳入一個列表類型的參數(由url路徑和處理類組成的元組)。
然後,調用Application的listen方法監聽服務器端口,事實上該方法會先創建一個HTTPServer實例,然後在HTTPServer實例上進行監聽,方法描述如下:

def listen(self, port, address="", **kwargs):
    """Starts an HTTP server for this application on the given port.

    This is a convenience alias for creating an `.HTTPServer`
    object and calling its listen method.  Keyword arguments not
    supported by `HTTPServer.listen <.TCPServer.listen>` are passed to the
    `.HTTPServer` constructor.  For advanced uses
    (e.g. multi-process mode), do not use this method; create an
    `.HTTPServer` and call its
    `.TCPServer.bind`/`.TCPServer.start` methods directly.

    Note that after calling this method you still need to call
    ``IOLoop.current().start()`` to start the server.

    Returns the `.HTTPServer` object.

    .. versionchanged:: 4.3
       Now returns the `.HTTPServer` object.
    """
    # import is here rather than top level because HTTPServer
    # is not importable on appengine
    from tornado.httpserver import HTTPServer
    server = HTTPServer(self, **kwargs)
    server.listen(port, address)
    return server

最後,執行IOLoop類的實例方法 start(),即可啓動服務器。

HelloWorld擴展

# coding: utf-8
import sys

reload(sys)
sys.setdefaultencoding('utf-8')

import tornado.ioloop
import tornado.web
import logging

from tornado.options import define, options

"""定義全局變量,這裏定義了一個端口"""
define("port", default=8888, help="run on the given port", type=int)


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


class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        greeting = self.get_argument('greeting', 'Hello')
        self.write(greeting + ',friendly user!')


if __name__ == "__main__":
    logging.basicConfig(stream=sys.stdout, level=logging.INFO,
                        format='%(asctime)s %(levelno)s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        )
    logging.info("start server ...")
    app = tornado.web.Application(handlers=[(r"/", IndexHandler), (r"/test", MainHandler)])
    app.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

這裏添加了兩個路由映射,直接輸入服務器地址加端口ip,則映射到MainHandler,輸出“hello world”。如果繼續加一層子路徑/test,則輸出“Hello,friendly user!”。

如果要使用中文,則必須在文件頭加上:

 # coding: utf-8
 import sys
 reload(sys)
 sys.setdefaultencoding('utf-8')

重載sys模塊並設置編碼方式爲utf-8。

如果要打印日誌,則需要在主函數裏面加上:

logging.basicConfig(stream=sys.stdout, level=logging.INFO,
                        format='%(asctime)s %(levelno)s %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S',
                        )

表示在控制檯輸出日誌,格式爲:年月日時分秒 日誌級別 日誌內容。

參數處理

get請求

上面的例子中get請求都沒有參數,如果get請求有參數呢?

定義處理類如下:

class ReverseHandler(tornado.web.RequestHandler):
    def get(self, input):
        self.write(input[::-1])

該處理類能接收get請求,並反序輸出請求參數。
路由映射如下:

handlers=[(r"/reverse/(\w+)", ReverseHandler), xxx]

\w+匹配1個或多個字母、數字或下劃線。括號的含義是讓Tornado保存匹配括號裏面表達式的字符串,並將其作爲請求方法的一個參數傳遞給RequestHandler類。

啓動服務器,通過地址欄發出get請求:http://localhost:8888/reverse/hello, 會將hello作爲參數,反轉輸出"olleh"。

post請求

對於post請求,通過post方法進行處理。
引入textwrap,並定義handler類如下:

class WrapHandler(tornado.web.RequestHandler):
    def post(self):
        text = self.get_argument('text')
        width = self.get_argument('width', 40)
        self.write(textwrap.fill(text, int(width)))

該處理類能接收post請求,並獲取兩個參數,分別是text和width,text未指定值,需要從命令行讀取。最終截取text參數的前40個字符輸出。
路由映射如下:

handlers=[(r"/wrap", WrapHandler), xxx]

post請求可以通過命令行curl xxx -d 指令發出:

curl http://localhost:8888/wrap -d text=Lorem+ipsum+dolor+sit+amet,+consectetuer+adipiscing+elit.

輸出結果如下(Tornado可以解析URLencoded和multipart結構的POST請求參數):

Lorem ipsum dolor sit amet, consectetuer

參考資料

[1]http://demo.pythoner.com/itt2zh/ch1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章