[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()

  

三、总结

 路由功能在设计时应该从最简单的方式开始,然后一步步的完善,比如:避免路由逻辑写死在代码中,代码优化。

原文地址:https://www.cnblogs.com/i-honey/p/8119971.html