Python开发【第十四篇】:Web框架本质
Web框架本质
众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#!/usr/bin/env python #coding:utf-8 import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, Seven") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost',8000)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main() |
上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。
python标准库提供的独立WSGI服务器称为wsgiref。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) return '<h1>Hello, web!</h1>' if __name__ == '__main__': httpd = make_server('', 8000, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever() |
自定义Web框架
一、框架
通过python标准库提供的wsgiref模块开发一个自己的Web框架
|
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
35
36
37
|
#!/usr/bin/env python #coding:utf-8 from wsgiref.simple_server import make_server def index(): return 'index' def login(): return 'login' def routers(): urlpatterns = ( ('/index/',index), ('/login/',login), ) return urlpatterns def RunServer(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return func() else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8000, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever() |
2、模板引擎
在上一步骤中,对于所有的login、index均返回给用户浏览器一个简单的字符串,在现实的Web请求中一般会返回一个复杂的符合HTML规则的字符串,所以我们一般将要返回给用户的HTML写在指定文件中,然后再返回。如:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>Index</h1> </body>
</html>

index.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form>
<input type="text" />
<input type="text" />
<input type="submit" />
</form>
</body>
</html>
login.html
|
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#!/usr/bin/env python # -*- coding:utf-8 -*- from wsgiref.simple_server import make_server def index(): # return 'index' f = open('index.html') data = f.read() return data def login(): # return 'login' f = open('login.html') data = f.read() return data def routers(): urlpatterns = ( ('/index/', index), ('/login/', login), ) return urlpatterns def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return func() else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8000, run_server) print "Serving HTTP on port 8000..." httpd.serve_forever() |
对于上述代码,虽然可以返回给用户HTML的内容以现实复杂的页面,但是还是存在问题:如何给用户返回动态内容?
- 自定义一套特殊的语法,进行替换
- 使用开源工具jinja2,遵循其指定语法
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>{{name}}</h1> <ul>
{% for item in user_list %}
<li>{{item}}</li>
{% endfor %}
</ul> </body>
</html>
index.html
|
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
#!/usr/bin/env python # -*- coding:utf-8 -*- from wsgiref.simple_server import make_server from jinja2 import Template def index(): # return 'index' # template = Template('Hello {{ name }}!') # result = template.render(name='John Doe') f = open('index.html') result = f.read() template = Template(result) data = template.render(name='John Doe', user_list=['alex', 'eric']) return data.encode('utf-8') def login(): # return 'login' f = open('login.html') data = f.read() return data def routers(): urlpatterns = ( ('/index/', index), ('/login/', login), ) return urlpatterns def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) url = environ['PATH_INFO'] urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return func() else: return '404 not found' if __name__ == '__main__': httpd = make_server('', 8000, run_server) print "Serving HTTP on port 8000..." httpd.serve_forever() |
遵循jinja2的语法规则,其内部会对指定的语法进行相应的替换,从而达到动态的返回内容,对于模板引擎的本质,参考另外一篇博客:白话tornado源码之褪去模板外衣的前戏
Python开发【第十四篇】:Web框架本质的更多相关文章
- [Python笔记]第十六篇:web框架之Tornado
Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...
- 【Python之路】第十五篇--Web框架
Web框架本质 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #coding:utf- ...
- 【Python之路】第十六篇--Web框架之Tornado
概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...
- python【第十四篇】HTML与CSS初遇
概述 HTML是英文Hyper Text Mark-up Language(超文本标记语言)的缩写,他是一种制作万维网页面标准语言(标记).相当于定义统一的一套规则,大家都来遵守他,这样就可以让浏览器 ...
- Python开发【第四篇】语句与函数
语句 statement 语句是由一些表达式组成,通常一条语句可以独立的执行来完成一部分事情,并且形成结果. 多条语句写在一行内要用分号分开 例子: print('hello world') #这是一 ...
- Android UI开发第二十四篇——Action Bar
Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式.在大多数的情况下,当你需要突出展现用户行为或全局导航的activity中使用action bar,因为acti ...
- 【转】Android UI开发第二十四篇——Action Bar
Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式.在大多数的情况下,当你需要突出展现用户行为或全局导航的activity中使用action bar,因为acti ...
- Python开发【第四篇】:Python基础之函数
三元运算 三元运算(三目运算),是对简单的条件语句的缩写. ? 1 2 3 4 5 # 书写格式 result = 值1 if 条件 else 值2 # 如果条件成立,那么将 “值1” 赋值给 ...
- python学习笔记(十 四)、web.py
使用web.py 通过python进行网页的编写,下面我们来简单了解一哈web.py 的使用 1 url处理 使用特定的url结构来解析我们发送的请求.如下面所示: urls = ( '/login' ...
- Python开发【第四篇】函数
函数的作用 函数可以让编程逻辑结构化以及模块化 无论是C.C++,Java还是Python,函数是必不可少的知识点,也是很重要的知识点,函数是完成一个功能的代码块,使用函数可以使逻辑结构变得更加清晰以 ...
随机推荐
- dede使用方法----如何去掉dede自带的版权
最近有朋友问如何将dede的Power by DedeCms去掉,一来为了安全,二来外链确实有些影响,这里分享下去除方法,需要的朋友可以参考下 自从dedecms织梦系统更新到6.7日的版本,底部 ...
- JAVA中AJAX的使用
AJAX<%@ page language="java" import="java.util.*" pageEncoding="UTF-8&qu ...
- 兼容性问题
直接在html文档中使用 来表示空格,在不同浏览器中的占位大小是不一样的. 因为不同浏览器默认的字体是不一样的,不同字体下的空格表示 占位大小不一致. 我们对 指定使用同样的字体就能让 显示同样的占位 ...
- matplotlib 和 pandas 两个包的安装
matplotlib是强大的python 绘图包.pandas 是强大的python分析工具包.numpy是强大的python统计包. 都超级好用,而且最近开始动手实践机器学习算法了.特此备注一下安装 ...
- 74.Android之四种启动模式
转载:http://www.cnblogs.com/meizixiong/archive/2013/07/03/3170591.html 一.启动模式介绍 启动模式简单地说就是Activity启动时的 ...
- 【BZOJ-3696】化合物 树形DP + 母函数(什么鬼)
3696: 化合物 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 165 Solved: 85[Submit][Status][Discuss] D ...
- HDU 4223 Dynamic Programming?(最小连续子序列和的绝对值O(NlogN))
传送门 Description Dynamic Programming, short for DP, is the favorite of iSea. It is a method for solvi ...
- RNN 入门教程 Part 2 – 使用 numpy 和 theano 分别实现RNN模型
转载 - Recurrent Neural Networks Tutorial, Part 2 – Implementing a RNN with Python, Numpy and Theano 本 ...
- 安卓开发30:AsyncTask的用法
http://blog.csdn.net/initphp/article/details/10392093 安卓开发笔记系列(43) 在开发Android应用时必须遵守单线程模型的原则: Andro ...
- NOIp2010 关押罪犯
二分+2-SAT 先预处理出所有的v,然后离散化一下,在那个的基础上二分,对于每次二分出的值约束边权超过所二分出的边权的两点. //OJ 1322 //by Cydiater //2015.8.26 ...