一、路由
1.1 什么是路由
簡單說,就是路怎么走。就是按照不同的路徑分發數據。
URL就是不同資源的路徑,不同路徑應該對應不同的應用程序來處理。
所以,代碼中要增加對路徑的分支處理。
一個簡單的路由需求:
| 路徑 | 內容 |
| / | 返回歡迎信息 |
| /python | 返回Hello Python |
| 其它路徑 | 返回404 |
1.2 什么時候處理路由
路由的處理需要在WSGI Server接收到HTTP請求后,WSGI Server解包封裝服務器環境變量,隨后就應該對request.path做處理,根據path調用相應的應用程序。
1.3 如何處理路由
路由處理最簡單的就是條件判斷,但需要判斷嚴謹。
二、路由處理
2.1 條件判斷
from wsgiref.simple_server import make_server
from webob import Request, Response, dec
@dec.wsgify
def app(request) -> Response:
print(request.method)
print(request.path)
print(request.query_string)
print(request.GET)
print(request.POST)
print(request.params)
res = Response()
if request.path == '/':
res.status_code = 200
res.content_type = 'text/html'
res.charset = 'utf-8'
res.body = '<h1>北京歡迎您</h1>'.encode()
elif request.path == '/python':
res.content_type = 'text/plain'
res.charset = 'gb2312'
res.body = '<h1>Hello Python</h1>'.encode()
else:
res.status_code = 404
res.body = '<h1>Not found</h1>'.encode()
return res
if __name__ == '__main__':
ip = '127.0.0.1'
port = 9999
server = make_server(ip, port, app)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.shutdown()
server.server_close()
2.2 函數化條件匹配
from wsgiref.simple_server import make_server
from webob import Request, Response, dec
def index(request: Request):
return Response('<h1>Welcome to BeiJing</h1>')
def showpython(request: Request):
return Response('<h1>Hello Python</h1>')
def notfound(request: Request):
res = Response()
res.body = '<h1>Not found</h1>'.encode()
res.status_code = 404
return res
ROUTETABLE = {
'/': index,
'/python': showpython
}
@dec.wsgify
def app(request) -> Response:
# if request.path == '/':
# return index(request)
# elif request.path == '/python':
# return showpython(request)
# else:
# return notfound(request)
return ROUTETABLE.get(request.path, notfound)(request)
if __name__ == '__main__':
ip = '127.0.0.1'
port = 9999
server = make_server(ip, port, app)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.shutdown()
server.server_close()
2.3 增加路由動態注冊
from wsgiref.simple_server import make_server
from webob import Request, Response, dec
def index(request: Request):
return Response('<h1>Welcome to BeiJing</h1>')
def showpython(request: Request):
return Response('<h1>Hello Python</h1>')
def notfound(request: Request):
res = Response()
res.body = '<h1>Not found</h1>'.encode()
res.status_code = 404
return res
ROUTETABLE = {}
def register(path, handler):
ROUTETABLE[path] = handler
register('/', index)
register('/python', showpython)
@dec.wsgify
def app(request) -> Response:
return ROUTETABLE.get(request.path, notfound)(request)
if __name__ == '__main__':
ip = '127.0.0.1'
port = 9999
server = make_server(ip, port, app)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.shutdown()
server.server_close()
2.4 路由封裝成類
from wsgiref.simple_server import make_server
from webob import Request, Response, dec, exc
class Application:
def notfound(self, request: Request):
res = Response()
res.status_code = 404
res.body = '<h1>Not found</h1>'.encode()
return res
ROUTETABLE = {}
@classmethod
def register(cls, path):
def _register(handler):
cls.ROUTETABLE[path] = handler
return handler
return _register
@dec.wsgify
def __call__(self, request) -> Response:
return self.ROUTETABLE.get(request.path, self.notfound)(request)
@Application.register('/')
def index(request: Request):
return Response('<h1>Welcome to BeiJing</h1>')
@Application.register('/python')
def showpython(request: Request):
return Response('<h1>Hello Python</h1>')
if __name__ == '__main__':
ip = '127.0.0.1'
port = 9999
server = make_server(ip, port, Application())
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.shutdown()
server.server_close()
2.5 簡化路由類
from wsgiref.simple_server import make_server
from webob import Request, Response, dec, exc
class Application:
ROUTETABLE = {}
@classmethod
def register(cls, path):
def _register(handler):
cls.ROUTETABLE[path] = handler
return handler
return _register
@dec.wsgify
def __call__(self, request) -> Response:
try:
return self.ROUTETABLE[request.path](request)
except:
raise exc.HTTPNotFound('你訪問的頁面被外星人劫持了')
@Application.register('/')
def index(request: Request):
return Response('<h1>Welcome to BeiJing</h1>')
@Application.register('/python')
def showpython(request: Request):
return Response('<h1>Hello Python</h1>')
if __name__ == '__main__':
ip = '127.0.0.1'
port = 9999
server = make_server(ip, port, Application())
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.shutdown()
server.server_close()
三、總結
路由功能在設計時應該從最簡單的方式開始,然后一步步的完善,比如:避免路由邏輯寫死在代碼中,代碼優化。
