1Python全栈之路系列之Tornado Web框架

简介:

Python全栈之路系列之Tornado Web框架


Tornado是一个Python web框架和异步网络库,起初由FriendFeed开发. 通过使用非阻塞网络I/O,Tornado可以支撑上万级的连接,处理长连接, WebSockets,和其他需要与每个用户保持长久连接的应用.


Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。

通过pip3快速自动安装tornado

1
pip3 install tornado

手动源码安装

1
2
3
4
tar xvzf tornado - x.x.tar.gz
cd tornado - x.x
python setup.py build
sudo python setup.py install

启动一个简单的tornado WebServer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
# _*_coding:utf-8 _*_
 
# 导入启动一个tornado所需要的模块
import  tornado.ioloop
import  tornado.web
 
# 创建一个类,继承tornado.web.RequestHandler类
class  MainHandler(tornado.web.RequestHandler):
     # 如果提交的方式是get方式,那么就执行get类
     def  get( self ):
         # write=返回字符串
         self .write( "Hello, world" )
         
# 路由映射系统,如果访问的路径没有在这个路由系统中,那么就报404
application  =  tornado.web.Application([
     # 视图,访问"/"的时候交给"MainHandler"类处理
     (r '/' , MainHandler),
])
 
if  __name__  = =  "__main__" :
     # 监听"8888"端口
     application.listen( 8888 )
     # 运行socket
     tornado.ioloop.IOLoop.instance().start()

通过Linux下的curl命令访问127.0.0.1:8888

1
2
3
ansheng@Darker:~$ curl  127.0 . 0.1 : 8888
Hello, world
ansheng@Darker:~$

模板路径的配置

选项 描述 调用示例
"tempalte_path": "template", HTML模板文件 self.render("template/index.html")
"static_path": "static", 静态文件的配置 <img src="/static/logo.jpg">
"static_url_prefix": "/img/", 静态文件的前缀 <img src="/img/logo.jpg">

一个示例叫你如何使用模板路径配置

python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/env python
# _*_coding:utf-8 _*_
 
import  tornado.ioloop
import  tornado.web
 
class  MainHandler(tornado.web.RequestHandler):
     def  get( self ):
         # render=返回一个html,查找的html文件路径默认是当前路径
         self .render( "template/index.html" )
         # self.redirect('/URL')  # 页面跳转
         
settings  =  {
     "tempalte_path" "template" ,   # 模板文件
     "static_path" "static" ,   # 静态文件的配置
     "static_url_prefix" "/img/" ,   # 静态文件的前缀
}
 
application  =  tornado.web.Application([
     (r '/' , MainHandler),
],  * * settings)
 
if  __name__  = =  "__main__" :
     application.listen( 8888 )
     tornado.ioloop.IOLoop.instance().start()

html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html lang = "en" >
<head>
     <meta charset = "UTF-8" >
     <title>Title< / title>
< / head>
<body>
 
<h1 style = "color: rebeccapurple" >Hello World!< / h1>
 
<img src = "/img/logo.jpg" >
 
< / body>
< / html>

curl一下

1
2
3
4
5
6
7
8
9
10
11
12
13
ansheng@Darker:~$ curl  127.0 . 0.1 : 8888
<!DOCTYPE html>
<html lang = "en" >
<head>
<meta charset = "UTF-8" >
<title>Title< / title>
< / head>
<body>
<h1 style = "color: rebeccapurple" >Hello World!< / h1>
<img src = "/img/logo.jpg" >
< / body>
< / html>
ansheng@Darker:~$

查看一下图片

1
2
3
4
5
6
7
8
9
ansheng@Darker:~$ curl  - 127.0 . 0.1 : 8888 / img / logo.jpg
HTTP / 1.1  200  OK
Server: TornadoServer / 4.4
Etag:  "cc1df4316e5f10c2aeddda15a5cad9e2"
Accept - Ranges: bytes
Last - Modified: Thu,  07  Jul  2016  01 : 46 : 10  GMT
Content - Type : image / jpeg
Date: Thu,  28  Jul  2016  14 : 45 : 14  GMT
Content - Length:  76459

根据用户的输入,动态的添加内容

python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/usr/bin/env python
# _*_coding:utf-8 _*_
 
import  tornado.ioloop
import  tornado.web
 
# 全局变量INPUT_LIST,用户接收用户提交过来的值
INPUT_LIST  =  []
 
class  MainHandler(tornado.web.RequestHandler):
     def  get( self ):
         # self.get_argument('val') 获取用户提交的数据
         val  =  self .get_argument( 'val' None )
         if  val:
             # 如果获取道了数据,那么就把获取到的数据添加到全局变量INPUT_LIST中
             INPUT_LIST.append(val)
         self .render( "template/index.html" , input_list = INPUT_LIST)
         
# 1.打开"index.html"文件,读取内容(包含特殊语法)
# 2.传过来的值与特殊的语法进行一个渲染
# 3.得到已经渲染之后的字符串
# 4.返回给用户渲染之后的字符串
 
settings  =  {
     "tempalte_path" "template" ,   # 模板文件
}
 
application  =  tornado.web.Application([
     (r '/' , MainHandler),
],  * * settings)
 
if  __name__  = =  "__main__" :
     application.listen( 8888 )
     tornado.ioloop.IOLoop.instance().start()

html代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang = "en" >
<head>
     <meta charset = "UTF-8" >
     <title>Title< / title>
< / head>
<body>
 
<! - -  提交方式为get,提交到 /  - - >
<form method = "post"  action = "/" >
     < input  type = "text"  name = "val"  / >
     < input  type = "submit"  / >
< / form>
 
<ul>
     { %  for  item  in  input_list  % }
     <li>{{ item }}< / li>
     { %  end  % }
< / ul>
 
< / body>
< / html>

wKiom1kVd7LzBZDXAAAlDbC1xr0050.png

自定义模板语言UIMethod和UIModule

模板语言分为三大类

代码块

1
2
3
{ %  for  item  in  input_list  % }
<li>{{ item }}< / li>
{ %  end  % }

` item `
一个表达式或者一个值,例如返回的时候传入一个参数NPM:

1
self .render( "template/index2.html" , npm = "NPM" )

前端页面接收

<p>{{ npm }}</p>

函数处理模板(uimethods和uimodules)

1
2
3
4
5
6
7
8
9
10
# uimethods.py
def  mtFunc( self , arg):
     return  'uimethods'
     
# uimodules.py
from  tornado.web  import  UIModule
 
class  mdClass(UIModule):
     def  render( self * args,  * * kwargs):
         return  'uimodules'

注册

1
2
3
4
5
6
7
8
import  uimethods as mt
import  uimodules as md
# 先导入上面两个模块,然后再settings字段加入以下内容
settings  =  {
     ........,
     'ui_methods' : mt,
     'ui_modules' : md,
}

使用

1
2
3
4
<! - -  ui_modules调用方式  - - >
{ %  module mdClass()  % }
<! - -  ui_methods调用方式  - - >
{{ mtFunc(val) }}

返回结果

wKioL1kVeAiAz-GXAAAcrNr_Phs241.png-wh_50

默认的函数、字段、类

方法 描述
escape tornado.escape.xhtml_escape的別名
xhtml_escape tornado.escape.xhtml_escape的別名
url_escape tornado.escape.url_escape的別名
json_encode tornado.escape.json_encode的別名
squeeze tornado.escape.squeeze的別名
datetime Python的datetime模组
handler 当前的 RequestHandler对象
request handler.request的別名
current_user handler.current_user的別名
locale handler.locale的別名
static_url handler.static_url的別名,对静态文件做缓存
xsrf_form_html handler.xsrf_form_html的別名

路由

基于正则的路由

1
2
3
4
5
6
7
8
9
10
class  MainHandler(tornado.web.RequestHandler):
     def  get( self * args,  * * kwargs):
         print (args)
         self .write( "Hello Wrold" )
         
application  =  tornado.web.Application([
     # 在路由中可以写入正则表达式
     (r '/(\d*)/(\w*)' , MainHandler),
     (r '/(?P<number>\d*)/(?P<nid>\w*)' , MainHandler),
])

二级域名的路由

二级域名这个功能实在Tornado中特有的,实现的代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class  WwwHandler(tornado.web.RequestHandler):
     def  get( self ):
         self .write("
          
class  MyHandler(tornado.web.RequestHandler):
     def  get( self ):
         self .write( "my.ansheng.me" )
         
application  =  tornado.web.Application([
     (r '/' , WwwHandler),
])
 
application.add_handlers( 'my.ansheng.me$' , [
     (r '/' , MyHandler)
])

本机的hosts文件内加入以下内容:

1
2
127.0 . 0.1  www.ansheng.me
127.0 . 0.1  my.ansheng.me

效果图

wKiom1kVeLCjOPkCAAA8CDKNzJc956.png

模板的继承与导入

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<! - -  layout.html  - - >
<!DOCTYPE html>
<html>
<head>
     <meta http - equiv = "Content-Type"  content = "text/html; charset=UTF-8" / >
     <link href = "{{static_url(" css / common.css ")}}"  rel = "stylesheet"  / >
     { %  block CSS  % }{ %  end  % }
< / head>
<body>
     <div  class = "pg-header" >
     
     < / div>
     { %  block RenderBody  % }{ %  end  % }
     <script src = "{{static_url(" js / jquery - 1.8 . 2.min .js ")}}" >< / script>
     { %  block JavaScript  % }{ %  end  % }
< / body>
< / html>
 
<! - -  index.html  - - >
{ %  extends  'layout.html' % }
{ %  block CSS  % }
     <link href = "{{static_url(" css / index.css ")}}"  rel = "stylesheet"  / >
{ %  end  % }
{ %  block RenderBody  % }
     <h1>Index< / h1>
     <ul>
     { %   for  item  in  li  % }
         <li>`item`< / li>
     { %  end  % }
     < / ul>
{ %  end  % }
{ %  block JavaScript  % }
{ %  end  % }

导入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<! - -  header.html  - - >
<div>
     <ul>
         <li> 1024 < / li>
         <li> 42 区< / li>
     < / ul>
< / div>
<! - -  index.html  - - >
<!DOCTYPE html>
<html>
<head>
     <meta http - equiv = "Content-Type"  content = "text/html; charset=UTF-8" / >
     <link href = "{{static_url(" css / common.css ")}}"  rel = "stylesheet"  / >
< / head>
<body>
     <div  class = "pg-header" >
         { %  include  'header.html'  % }
     < / div>
     <script src = "{{static_url(" js / jquery - 1.8 . 2.min .js ")}}" >< / script>
< / body>
< / html>









本文转自 Edenwy  51CTO博客,原文链接:http://blog.51cto.com/edeny/1925116,如需转载请自行联系原作者
目录
相关文章
|
10天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
【4月更文挑战第9天】本文对比了Python三大Web框架Django、Flask和Pyramid。Django功能全面,适合快速开发,但学习曲线较陡;Flask轻量灵活,易于入门,但默认配置简单,需自行添加功能;Pyramid兼顾灵活性和可扩展性,适合不同规模项目,但社区及资源相对较少。选择框架应考虑项目需求和开发者偏好。
|
4天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
4天前
|
前端开发 数据挖掘 API
使用Python中的Flask框架进行Web应用开发
【4月更文挑战第15天】在Python的Web开发领域,Flask是一个备受欢迎的轻量级Web框架。它简洁、灵活且易于扩展,使得开发者能够快速地构建出高质量的Web应用。本文将深入探讨Flask框架的核心特性、使用方法以及在实际开发中的应用。
|
6天前
|
关系型数据库 数据库 开发者
Python中的Peewee框架:轻量级ORM的优雅之旅
【4月更文挑战第13天】在Python的众多ORM框架中,Peewee以其轻量级、简洁和易于上手的特点,受到了许多开发者的青睐。Peewee的设计理念是“小而美”,它提供了基本的ORM功能,同时保持了代码的清晰和高效。本文将深入探讨Peewee的核心概念、使用场景以及实战应用,帮助读者更好地理解和使用这一框架。
|
6天前
|
SQL API 数据库
Python中的SQLAlchemy框架:深度解析与实战应用
【4月更文挑战第13天】在Python的众多ORM(对象关系映射)框架中,SQLAlchemy以其功能强大、灵活性和易扩展性脱颖而出,成为许多开发者首选的数据库操作工具。本文将深入探讨SQLAlchemy的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
16天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南
|
17天前
|
数据采集 Java API
python并发编程: Python使用线程池在Web服务中实现加速
python并发编程: Python使用线程池在Web服务中实现加速
17 3
python并发编程: Python使用线程池在Web服务中实现加速
|
3月前
|
测试技术 UED Python
使用Python构建自动化测试框架
本文介绍了如何使用Python语言构建一个强大的自动化测试框架,该框架可以帮助开发人员在软件开发过程中进行高效的测试工作。通过使用Python的强大功能和第三方库,我们可以轻松地编写、运行和管理各种测试用例,并生成详细的测试报告,提高软件质量和开发效率。
|
3月前
|
测试技术 开发者 Python
Python自动化测试与单元测试框架:提升代码质量与效率
在软件开发过程中,测试是不可或缺的环节。Python作为一门广泛应用的编程语言,拥有丰富的自动化测试和单元测试框架,例如unittest和pytest。本文将介绍Python自动化测试的重要性,并深入探讨这两个主流的单元测试框架的特点、使用方法以及优势。通过学习和应用这些框架,开发者可以提高代码质量、提升开发效率,并确保软件在不断迭代中保持稳定。
|
3月前
|
测试技术 Python
Python自动化测试与单元测试框架
自动化测试在软件开发中扮演着重要的角色,可以减少人工测试的时间和成本,提高软件质量。而Python作为一种流行的编程语言,其丰富的库和框架可以让测试变得更加容易和高效。本文将介绍Python自动化测试和单元测试框架,包括unittest和pytest的使用方法、优点和缺点,以及如何根据项目需求选择合适的框架。