[Python web開發] 路由實現 (三)
阿新 • • 發佈:2017-12-28
keyboard route eth rup 1.3 分發 簡化 query 需要
一、路由
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()
三、總結
路由功能在設計時應該從最簡單的方式開始,然後一步步的完善,比如:避免路由邏輯寫死在代碼中,代碼優化。
[Python web開發] 路由實現 (三)