【从零学习python 】91. 使用装饰器和字典管理请求路径的简洁Web应用

2024-02-29 20:36:12 浏览数 (2)

导入必要的模块
代码语言:javascript复制
from wsgiref.simple_server import make_server
from utils import load_html, load_template

这两行代码首先导入了make_server函数和自定义的load_htmlload_template函数,以便后续使用。

创建路由字典
代码语言:javascript复制
g_url_route = {}

定义了一个全局变量g_url_route作为路由字典,用于保存请求路径和处理函数之间的对应关系。

装饰器函数route
代码语言:javascript复制
def route(url):
    def handle_action(action):
        g_url_route[url] = action

        def do_action(start_response):
            return action(start_response)

        return do_action

    return handle_action

route是一个装饰器函数,在定义路由时使用。它接受一个url参数,并返回一个内部函数handle_action。在内部函数中,它将请求路径url与处理函数action进行关联,并定义了一个新的函数do_action,该函数接受start_response参数并执行action函数。最后返回do_action函数。

路由定义及处理函数
代码语言:javascript复制
@route('/index.html')
@route('/')
def show_home(start_response):
    return load_html('/index.html', start_response)

这是一个示例,使用route装饰器定义了两个路由:/index.html/,并将它们分别与show_home函数关联起来。当请求路径匹配到这两个路由之一时,将执行show_home函数。

代码语言:javascript复制
@route('/test.html')
def show_test(start_response):
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
    return ['我是一段普通的文字'.encode('utf-8')]

这是另一个示例,使用route装饰器定义了一个路由/test.html,并将其与show_test函数关联起来。当请求路径匹配到该路由时,将执行show_test函数。该函数设置了响应头信息,并返回一段普通的文字作为响应内容。

代码语言:javascript复制
@route('/info.html')
def show_info(start_response):
    return load_template('/info.html', start_response, name='张三', age=18)

同样使用route装饰器定义了一个路由/info.html,并将其与show_info函数关联起来。当请求路径匹配到该路由时,将执行show_info函数。该函数使用load_template函数加载/info.html模板,并传入nameage参数进行渲染。

请求处理函数application
代码语言:javascript复制
def application(environ, start_response):
    file_name = environ.get('PATH_INFO')
    try:
        return g_url_route[file_name](start_response)
    except Exception:
        start_response('404 NOT FOUND', [('Content-Type', 'text/html;charset=utf-8')])
        return ['对不起,界面未找到'.encode('utf-8')]

application函数是WSGI应用程序的入口点。它接受environstart_response两个参数,用于处理HTTP请求。首先,获取请求路径file_name。然后,尝试从路由字典中找到匹配的处理函数,并执行该函数。如果找不到对应的处理函数,则返回404状态码及相应的错误信息。

服务器启动并监听
代码语言:javascript复制
if __name__ == '__main__':
    httpd = make_server('', 8000, application)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()

这部分代码用于启动服务器并监听指定端口(8000)。当程序被直接运行时(而不是作为模块导入),将创建一个WSGI服务器并调用application函数来处理请求。同时打印提示信息表示服务器正在运行,并通过httpd.serve_forever()实现持续监听。

完整代码
代码语言:javascript复制
from wsgiref.simple_server import make_server
from utils import load_html, load_template

g_url_route = {}


def route(url):
    def handle_action(action):
        g_url_route[url] = action

        def do_action(start_response):
            return action(start_response)

        return do_action

    return handle_action


@route('/index.html')
@route('/')
def show_home(start_response):
    return load_html('/index.html', start_response)


@route('/test.html')
def show_test(start_response):
    start_response('200 OK', [('Content-Type', "text/html;charset=utf-8")])
    return ['我是一段普通的文字'.encode('utf-8')]


@route('/info.html')
def show_info(start_response):
    return load_template('/info.html', start_response, name='张三', age=18)


def application(environ, start_response):
    file_name = environ.get('PATH_INFO')
    try:
        return g_url_route[file_name](start_response)
    except Exception:
        start_response('404 NOT FOUND', [('Content-Type', 'text/html;charset=utf-8')])
        return ['对不起,界面未找到'.encode('utf-8')]


if __name__ == '__main__':
    httpd = make_server('', 8000, application)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()

0 人点赞