📜  Python路由(1)

📅  最后修改于: 2023-12-03 14:46:47.836000             🧑  作者: Mango

Python 路由

路由是 Web 框架(比如 Flask、Django 等)中非常重要的概念,它定义了客户端请求特定 URL 时应该触发哪个函数。在 Python 中,有多种方式可以实现路由,包括:

  • Flask 的装饰器方式
  • Django 的 URL 配置文件方式
  • Bottle 的函数名方式
  • 纯 Python 实现的路由器

下面我们来逐一介绍。

Flask 装饰器方式

Flask 是一个非常流行的 Python Web 框架,它的路由实现非常简单,主要是通过装饰器实现。比如:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

上面的代码定义了一个根路由 /,当客户端请求该 URL 时,会触发 hello_world() 函数。

除了根路由,我们还可以定义其它的路由,比如:

@app.route('/user/<username>')
def show_user_profile(username):
    return 'User %s' % username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    return 'Post %d' % post_id

上面的代码分别定义了两个路径参数路由,/user/<username> 可以匹配类似 /user/zhangsan/user/mary 这样的 URL,其中 <username> 是路径参数,会被传递到 show_user_profile(username) 函数中;同理,/post/<int:post_id> 可以匹配类似 /post/123/post/456 这样的 URL,其中 <int:post_id> 也是路径参数,但它只能匹配整数,并且会被转换成整数类型,传递到 show_post(post_id) 函数中。

Django URL 配置文件方式

Django 是 Python Web 框架中的另一位巨佬,同样支持路由功能,并且比 Flask 更加强大、灵活,但也更加复杂。它的路由主要是通过 URL 配置文件(urls.py)实现的,比如:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('user/<int:user_id>/', views.user_detail, name='user_detail'),
    path('post/<int:post_id>/', views.post_detail, name='post_detail'),
]

上面的代码定义了三个路由,'' 对应根路由,'user/<int:user_id>/' 对应 /user/123/ 这样的 URL,'post/<int:post_id>/' 对应 /post/456/ 这样的 URL。其中,<int:user_id><int:post_id> 都是路径参数,并且只匹配整数类型。这些路由会分别触发 views.indexviews.user_detailviews.post_detail 这三个函数。

Bottle 函数名方式

Bottle 是一个小巧但功能强大的 Python Web 框架,它的路由非常简单,只需要将路径名作为函数名即可,比如:

from bottle import run, route

@route('/')
def index():
    return "Hello, world!"

@route('/user/<username>')
def show_user(username):
    return "Hello, %s!" % username

上面的代码定义了两个路由,'/' 对应根路由,当客户端请求该 URL 时,会触发 index() 函数;'/user/<username>' 对应 /user/zhangsan/ 这样的 URL,其中 <username> 是路径参数,会被传递到 show_user(username) 函数中。

纯 Python 实现的路由器

如果你不想依赖任何框架,也可以通过纯 Python 实现一个简单的路由器。比如:

import re

class Router:
    def __init__(self):
        self.routes = []

    def add_route(self, path, handler):
        self.routes.append((re.compile(path), handler))

    def match_route(self, url):
        for route, handler in self.routes:
            if route.search(url):
                return handler
        return None

    def __call__(self, environ, start_response):
        url = environ['PATH_INFO']
        handler = self.match_route(url)
        if handler is not None:
            response_body = handler(environ)
        else:
            response_body = b'404 Not Found'
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [response_body]

上面的代码实现了一个简单的路由器,它的使用方式是:

router = Router()

@router.add_route('/hello', lambda env: b'Hello, world!')
def hello_world(env):
    return b'Hello, world!'

@router.add_route('/user/(?P<username>[^/]+)', lambda env: b'Hello, ' + env['USERNAME'])
def hello_user(env):
    return b'Hello, ' + env['USERNAME']

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    httpd = make_server('', 8000, router)
    print('Serving on port 8000...')
    httpd.serve_forever()

上面的代码使用了 Router 类定义了两个路由,'/hello' 对应 /hello 这样的 URL,'/user/(?P<username>[^/]+)' 对应 /user/zhangsan/user/mary 这样的 URL,其中 (?P<username>[^/]+) 表示路径参数,会被传递到 env 字典中的 USERNAME 键中。

最后,我们通过 make_server 启动了一个简单的 Web 服务器,并注册了 Router 实例作为处理函数,这样客户端请求 URL 时就可以触发相应的路由处理函数了。

完整代码请参考 router.py

以上就是 Python 路由的介绍,希望对大家有所帮助!