[Python web开发] 路由实现 (三)
一、路由
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()
三、总结
路由功能在设计时应该从最简单的方式开始,然后一步步的完善,比如:避免路由逻辑写死在代码中,代码优化。