博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python开发【第十四篇】:Web框架本质
阅读量:4348 次
发布时间:2019-06-07

本文共 4746 字,大约阅读时间需要 15 分钟。

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
from 
wsgiref.simple_server 
import 
make_server
 
 
def 
RunServer(environ, start_response):
    
start_response(
'200 OK'
, [(
'Content-Type'
'text/html'
)])
    
return 
[bytes(
'<h1>Hello, web!</h1>'
, encoding
=
'utf-8'
), ]
 
 
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写在指定文件中,然后再返回。如:

 
index.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'
    
= 
open
(
'index.html'
)
    
data 
= 
f.read()
    
return 
data
 
 
def 
login():
    
# return 'login'
    
= 
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,遵循其指定语法
 
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')
 
    
= 
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'
    
= 
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的语法规则,其内部会对指定的语法进行相应的替换,从而达到动态的返回内容,对于模板引擎的本质,参考另外一篇博客:

 

转载于:https://www.cnblogs.com/caidapeng/p/10469418.html

你可能感兴趣的文章
C# 创建 读取 更新 XML文件
查看>>
KD树
查看>>
VsVim - Shortcut Key (快捷键)
查看>>
HDU5447 Good Numbers
查看>>
08.CXF发布WebService(Java项目)
查看>>
java-集合框架
查看>>
RTMP
查看>>
求一个数的整数次方
查看>>
点云PCL中小细节
查看>>
铁路信号基础
查看>>
RobotFramework自动化2-自定义关键字
查看>>
CMU Bomblab 答案
查看>>
技术分析淘宝的超卖宝贝
查看>>
Azure云服务托管恶意软件
查看>>
My安卓知识6--关于把项目从androidstudio工程转成eclipse工程并导成jar包
查看>>
旧的起点(开园说明)
查看>>
生产订单“生产线别”带入生产入库单
查看>>
crontab导致磁盘空间满问题的解决
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>