python web的第二個(gè)重要的框架--->Tornado
- 官方中文文檔
- tornado特點(diǎn)~功能少但是非常精巧的一個(gè)web框架
- 高并發(fā)高性能,異步非阻塞IO,websocket長連接,內(nèi)置高性能HTTP服務(wù)器
pip install tornado 安裝tornado模塊
# tornado程序開發(fā)可以在windows下進(jìn)程来惧,但是項(xiàng)目部署一定要在linux上進(jìn)行部署.
- 編寫Tornado項(xiàng)目
- 注意:tornado web程序純手工開發(fā),不像Django一樣自動(dòng)生成項(xiàng)目結(jié)構(gòu),要注意編程步驟
- 引入需要的模塊
from tornado.web import Application, RequestHandler
form tornado.ioloop import IOLoop
- RequestHandler:tornado web框架核心的一個(gè)處理類,主要進(jìn)行用戶請(qǐng)求對(duì)象的處理
- Application:tornado web框架核心的處理類,主要進(jìn)行web應(yīng)用程序的包裝
- IOLoop:tornado web服務(wù)器的核心處理類,主要進(jìn)行輪詢監(jiān)聽請(qǐng)求
- 開發(fā)視圖處理類
- 繼承 RequestHandler 妓肢,為了處理不同的請(qǐng)求方式授段,需要重寫父類中的請(qǐng)求處理方法
# 定義一個(gè)視圖處理類
class IndexHandler(RequestHandler):
# 重寫父類處理get請(qǐng)求的方法
def get(self):
# 通過self.write()可以直接向客戶端響應(yīng)數(shù)據(jù)
self.write(“hello tornado!”)
- 定義web應(yīng)用程序,啟動(dòng)服務(wù)器
# 程序運(yùn)行的入口
if __name__ == "__main__":
# 根據(jù)視圖處理類構(gòu)建一個(gè)web application
app = Application(
[
# 定義路由訪問
(r’/’, IndexHandler),
]
)
# 監(jiān)聽端口
app.listen(8000)
# 啟用tornado內(nèi)置服務(wù)器事件輪詢監(jiān)聽
IOLoop.current().start()
- 此時(shí)一個(gè)最基礎(chǔ)的tornado項(xiàng)目創(chuàng)建成功秸架,此時(shí)就可以添加各種功能豐富項(xiàng)目
# 引入需要的模塊服務(wù)器模塊
from tornado.httpserver import HTTPServer
......
#將創(chuàng)建好的APP添加到服務(wù)器中唯沮,再進(jìn)行輪詢監(jiān)聽
server = HTTPServer(app)
server.listen(8000)
# 將web application 部署到Server中
server = HTTPServer(app)
server.bind(8000)# 綁定8000端口
server.start() # 啟動(dòng)服務(wù)器伏尼,如果不設(shè)置參數(shù)或者參數(shù)為1忿檩,默認(rèn)啟動(dòng)1個(gè)進(jìn)程
# 不設(shè)置參數(shù)或者參數(shù)為0,根據(jù)當(dāng)前操作系統(tǒng)的核心數(shù)量創(chuàng)建進(jìn)程數(shù)量
# 如果設(shè)置了大于0的參數(shù)爆阶,默認(rèn)啟動(dòng)指定數(shù)量的進(jìn)程
# define定義變量燥透;options獲取變量
from tornado.options import define, options
# 定義一個(gè)變量,用于保存端口
define("port", default=8000, type=int, help="端口默認(rèn)使用8000")
#取出變量用 :options.port
server.bind(options.port)
#引入需要的模塊
from tornado.options import define, options, parse_command_line
# 定義變量
define("port", default=8000, help="默認(rèn)8000扰她,可通過--port=9000來指定")
#在啟動(dòng)程序中監(jiān)聽命令行參數(shù)
if __name__ == "__main__":
# 開始監(jiān)聽接受命令行參數(shù)數(shù)據(jù)~命令行的數(shù)據(jù)參數(shù)兽掰,必須是通過define指定
parse_command_line()
# 當(dāng)我們啟動(dòng)服務(wù)器時(shí)可以通過輸入 python demo01.py --port=8000
# 應(yīng)用程序設(shè)定為接受命令行參數(shù)
#使用同一個(gè)web應(yīng)用程序,啟動(dòng)多個(gè)獨(dú)立的進(jìn)程
python demo.py --port=8000 工作在8000端口的一個(gè)單進(jìn)程單線程的程序
python demo.py --port=9000 工作在9000端口的一個(gè)單進(jìn)程單線程的程序
#多個(gè)進(jìn)程手工部署
#web應(yīng)用程序就是多個(gè)獨(dú)立的進(jìn)程共同工作提供服務(wù)
#場景:項(xiàng)目需要更新時(shí)~添加了一個(gè)非常重要的功能[3個(gè)獨(dú)立進(jìn)程]
#停止1個(gè)進(jìn)程~更新代碼~重新部署啟動(dòng)[其他2個(gè)進(jìn)程正常工作徒役,
#不會(huì)影響用戶的體驗(yàn)~不會(huì)因?yàn)橄到y(tǒng)更新需要服務(wù)器重啟導(dǎo)致業(yè)務(wù)中斷]
- 設(shè)置網(wǎng)頁和靜態(tài)資源, debug
#導(dǎo)入模塊
import os
BASE_DIR=os.path.dirname(__file__)
app = Application(
......
# 添加配置孽尽,告訴tornado我們的網(wǎng)頁模板在項(xiàng)目的那個(gè)位置
template_path=os.path.join(BASE_DIR, "templates"),
# 添加配置,告訴tornado我們的靜態(tài)資源文件在項(xiàng)目那個(gè)位置
static_path=os.path.join(BASE_DIR, "static"),
# debug配置~默認(rèn)True忧勿,項(xiàng)目發(fā)布修改為False杉女,顯示的是錯(cuò)誤信息
debug=True,
)
- get/post參數(shù)處理[表單處理]以及模板語法
# get post 接收傳遞數(shù)據(jù)
def get(self):
# get特有的接受參數(shù)方式
name = self.get_query_argument("name")
fav = self.get_query_arguments("fav")
def post(self):
# post特有的接受參數(shù)方式
account = self.get_body_argument("account")
fav = self.get_body_arguments("fav")
# 通用接受參數(shù)方式
name = self.get_argument("name")
fav = self.get_arguments("fav")
# 返回?cái)?shù)據(jù)
user = {"name": name}
self.render("index.html", user=user)
# 模板語法,jinjia2
{% if books %}
{% else %}
{% end %}
{% for book in books%}
書名:{{book['name']}}
單價(jià):{{book['price']}}
數(shù)量:{{book['buycount']}}
小計(jì):{{book['price'] * book['buycount']}} #可以計(jì)算鸳吸,但沒有 empty
{% end %}