1. 程式人生 > >[Python web開發] 路由實現 (三)

[Python web開發] 路由實現 (三)

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開發] 路由實現 (三)