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兼顾灵活性和可扩展性,适合不同规模项目,但社区及资源相对较少。选择框架应考虑项目需求和开发者偏好。
|
1天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
9 0
|
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的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
7天前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。
|
9天前
|
JavaScript 前端开发 Docker
全栈开发实战:结合Python、Vue和Docker进行部署
【4月更文挑战第10天】本文介绍了如何使用Python、Vue.js和Docker进行全栈开发和部署。Python搭配Flask创建后端API,Vue.js构建前端界面,Docker负责应用的容器化部署。通过编写Dockerfile,将Python应用构建成Docker镜像并运行,前端部分使用Vue CLI创建项目并与后端交互。最后,通过Nginx和另一个Dockerfile部署前端应用。这种组合提升了开发效率,保证了应用的可维护性和扩展性,适合不同规模的企业使用。
|
Web App开发 存储 测试技术
|
8天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。

热门文章

最新文章