Web框架解析
Web通過Socket來監聽客戶端,,一旦發現客戶發送的信息立刻接受。接受之后在服務端查找客戶的請求,找到請求返回給用戶,斷開。這是一個連接,不斷的接收,不斷的返回。
#!/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, Wulaoer")
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1',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。
#!/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框架
#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server
def wulaoer():
return 'Hi, How are you wulaoer?'
def laowu():
return 'Hi, How are you laowu?'
def routers():
urlpatterns = (
('/wulaoer/',wulaoer),
('/laowu/',laowu),
)
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、模版引擎
在上一步驟中,對于所有的wulaoer、laowu均返回給用戶瀏覽器一個簡單的字符串,在現實的Web請求中一般會返回一個復雜的符號HTML規則的字符串,所以我們一般將要返回給用戶的HTML寫在指定文件中,然后再返回。如:


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Hi, how are you laowu!</h1> </body> </html>


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Hi, how are you wulaoer!</h1> </body> </html>
#!/usr/bin/env python
# --*--coding:utf-8 --*--
from wsgiref.simple_server import make_server
from jinja2 import Template
import time
'''
內容展示,先讀取打開html在讀取內容,展示
'''
def laowu():
# return 'Hi, laowu'
f = open('html/laowu.html')
data = f.read()
return data
def wulaoer():
# return 'Hi, wulaoer'
f = open('html/wulaoer.html')
data = f.read()
return data
'''
定義路徑列表
'''
url_list = (
('/laowu/',laowu),
('/wulaoer/',wulaoer),
)
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
func = None
'''循環列表如果存在就暫時不存在報錯404'''
for item in url_list:
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()
上述代碼只能返回給用戶HTML的內容,現實復雜的頁面,還是存在問題的:如何給用戶返回動態內容?
自定義一套特殊的語法,進行替換
使用開源的工具jinja2,遵循其指定語法


<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>{{ name }}</h1> <ul> {% for item in user_list %} <li>{{ item }}</li> {% endfor %} </ul> </body> </html>
#!/usr/bin/env python
# --*--coding:utf-8 --*--
from wsgiref.simple_server import make_server
from jinja2 import Template
'''
利用read讀取html的內容
'''
def index():
f = open('html/index.html')
result = f.read()
template = Template(result)
data = template.render(name='laowu', user_list=['Bom', 'Tom'])
return data.encode('utf-8')
def laowu():
# return 'Hi, laowu'
f = open('html/laowu.html')
data = f.read()
return data
def wulaoer():
# return 'Hi, wulaoer'
f = open('html/wulaoer.html')
data = f.read()
return data
url_list = (
('/laowu/',laowu),
('/index/',index),
('/wulaoer/',wulaoer),
)
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
func = None
for item in url_list:
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()
遵循jinja2的語法規則,其內部會對指定的語法進行相應的替換,從而達到動態的返回內容,對于模版引擎的本質。
內容參考鏈接:http://www.cnblogs.com/wupeiqi/articles/5237672.html