(五)Flask之深入剖析路由源码

这篇具有很好参考价值的文章主要介绍了(五)Flask之深入剖析路由源码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 路由(Route)这个概念在所有web框架中都非常重要,它是用于定义URL和对应的处理函数(视图)之间的映射关系。通过定义路由,可以使web框架应用程序能够响应不同的URL请求,并执行相应的逻辑。

源码剖析:

在Flask项目(比如下面这个hello world项目)刚启动时,Flask内部肯定会将所有的路由和视图创建对应关系。

from flask import Flask

app = Flask(__name__)


@app.route('/index', methods=['GET', 'POST'])
def index():
    return 'hello world'


if __name__ == '__main__':
    app.run('localhost', 4000)

分析源码:

当程序运行到@app.route('/index', methods=['GET', 'POST'])时,由于@语法糖的存在,会立刻执行route函数,所以进入route函数源码跟踪下:

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

app对象的route函数执行会返回decorator函数,即@decorator 等价于 @app.route(‘/index’, methods=[‘GET’, ‘POST’])

@语法糖的存在,会立刻执行@decorator

即decorator(index函数)

【因为程序下方没有执行index()函数,所以不用继续看@语法糖的第二步(在《(三)Flask前置知识栈——装饰器》这篇文章有详解)】

继续看route函数源码,decorator(index函数)对应—>decorator中的参数f就是index函数。

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

self.add_url_rule(rule, endpoint, f, **options)

源码中的这一句是关键,功能就是添加路由和视图函数的对应规则。

继续追踪源码,看下这个函数:

【注意add_url_rule()函数在Flask(__name__)这个对象中】

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

重点就是上图中红框部分。


简单剖析一波上图的add_url_rule()源码:

add_url_rule()方法是在Flask应用程序中注册URL规则的方法。

def add_url_rule(
    self,
    rule: str,
    endpoint: t.Optional[str] = None,
    view_func: t.Optional[ft.RouteCallable] = None,
    provide_automatic_options: t.Optional[bool] = None,
    **options: t.Any,
) -> None:
	"""
	*   rule:URL规则的字符串表示,对应'/index'。
	*   endpoint:可选参数,指定URL规则的名称(即终点)。
	*   view_func:可选参数,指定与URL规则关联的处理函数(视图函数)。
	*   provide_automatic_options:可选参数,控制是否自动提供OPTIONS方法。
	"""

首先,方法会对参数进行处理和验证:

# 如果没有指定`endpoint`,则根据`view_func`自动生成一个。
if endpoint is None:
    endpoint = _endpoint_from_view_func(view_func)
options["endpoint"] = endpoint


# 从options参数中弹出`methods`字段,并根据不同情况设置默认值为"GET"。最后,将`methods`转换为大写,并确保它是一个集合。
methods = options.pop("methods", None)
if methods is None:
    methods = getattr(view_func, "methods", None) or ("GET",)
if isinstance(methods, str):
    raise TypeError("Allowed methods must be a list of strings, for example: @app.route(..., methods=['POST'])")
methods = {item.upper() for item in methods}

接下来,根据view_func的属性和参数值,设置是否自动提供OPTIONS方法(文末会简单讲下这个是啥玩意):

# 如果没有指定`provide_automatic_options`,则从`view_func`的属性中获取。
if provide_automatic_options is None:
    provide_automatic_options = getattr(view_func, "provide_automatic_options", None)

# 如果仍然未指定,则根据methods是否包含"OPTIONS"来决定是否自动提供OPTIONS方法。
if provide_automatic_options is None:
    if "OPTIONS" not in methods:
        provide_automatic_options = True
        required_methods.add("OPTIONS")
    else:
        provide_automatic_options = False

接下来,将必需的方法添加到methods集合中,并创建一个Rule对象来表示URL规则:

# 将必需的方法合并到`methods`集合中(文末会讲这样的作用)
methods |= required_methods 

# 使用`url_rule_class`创建一个`Rule`对象来表示URL规则
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options

# 将rule添加到应用程序的URL映射中。
self.url_map.add(rule)

最后,如果指定了view_func,则将其关联到endpoint,并进行冲突检查:

if view_func is not None:
    old_func = self.view_functions.get(endpoint)
    if old_func is not None and old_func != view_func:
        raise AssertionError(f"View function mapping is overwriting an existing endpoint function: {endpoint}")
    self.view_functions[endpoint] = view_func

如果之前已经有一个与endpoint关联的处理函数,则会引发AssertionError(熟悉吗?在装饰器那篇引出的那个问题Flask就是在这抛出的异常!!!)。

总结:add_url_rule()方法用于向Flask应用程序添加URL规则。它解析和验证参数,设置默认值,并创建和注册Rule对象来表示URL规则。然后,将处理函数与URL规则关联,并进行必要的冲突检查。


继续按①追踪源码:

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码
(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

鄙人简单翻译一下:

一个Rule代表一个URL模式。“Rule”有一些选项会改变它的行为方式,并传递给“Rule”构造函数。

注意,除了规则字符串之外,所有参数必须为关键字参数,以免在Werkzeug升级时破坏应用程序。

说大白话就是:

Rule类对URL模式进行解析和存储。Rule类表示一个URL规则,并包含与之相关联的信息,如URL模式、HTTP方法、处理函数等。

继续按②追踪源码:

进入url_map:

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

进入url_map_class

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

鄙人简单翻译一下:

map类存储所有URL规则和一些配置参数。一些配置值仅存储在’ Map '实例,因为它们影响所有规则,其他只是默认值

并且可以为每个规则重写。注意,必须指定所有除了作为关键字参数的’ rules '之外的参数!

总之,一句话:

Map是一个URL映射器,它用于存储和管理应用程序中所有的URL规则。

继续追踪Map类中的add()函数(注释讲的很清楚了~):

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

继续按③追踪源码(文末会简单讲一下这行源码):

(五)Flask之深入剖析路由源码,Flask框架从入门到实战,flask,python,后端,路由,源码

上面是三条线分开剖析的源码,只是简单分析,后续会慢慢深入。

view_functions、Map和Rule放一起看看:

view_functionsMapRule之间存在密切的关系。它们是Flask框架中用于处理URL路由的重要组件。

  • view_functions是Flask应用程序对象的一个属性,存储了应用程序中所有路由终点(endpoint)与对应视图函数(view function)之间的映射关系。它是一个字典,键是路由的终点名称,值是对应的视图函数。通过app.view_functions可以访问和操作这个字典。

  • Map是一个URL映射器,用于存储和管理应用程序中的所有URL规则。它是werkzeug.routing.Map类的实例,通过app.url_map可以访问应用程序的Map对象。Map类提供了添加、查找和操作URL规则的方法,包括add()match()iter_rules()等。

  • Rule是URL规则的表示,它定义了一个URL模式、绑定的视图函数、可接受的请求方法等信息。Rule类是werkzeug.routing.Rule类的实例,作为Map对象的一部分使用。每个Rule对象都有一个唯一的终点(endpoint),用于标识该规则。Map类使用Rule对象来存储和管理URL规则。

关系如下:

  • 在定义Flask应用程序时,我们使用@app.route()装饰器来创建URL规则,并将路由终点和视图函数关联起来。这些URL规则会被存储在Map对象中,通过app.url_map访问。
  • 在调用app.route()装饰器时,Flask框架内部会创建一个Rule对象,表示这个URL规则。然后,Rule对象会添加到Map对象中,构成了整个URL映射关系。
  • Map对象使用view_functions属性来查找和调用对应的视图函数。当请求到达时,Map会根据请求的URL路径和HTTP方法,在内部查找匹配的Rule对象,并从中获取绑定的视图函数。
  • 通过view_functions字典和Map对象的结合,Flask能够实现自动路由和请求处理的功能。它将URL的终点(endpoint)作为键,从view_functions中查找对应的视图函数;同时,根据请求的URL和方法,从Map中查找匹配的Rule对象,并提取其中的视图函数进行调用。

可见,view_functionsMapRule是Flask框架中处理URL路由的关键组件,它们相互协作,才能实现灵活的路由管理和请求处理机制。

综上—添加路由的两种方式:

from flask import Flask

app = Flask(__name__)
app.config.from_object()


# 方式一    (就用这个!)
@app.route('/index', methods=['GET', 'POST'])
def index():
    return 'index'


def order():
    return 'order'


# 方式二
app.add_url_rule('/order', view_func=order)

if __name__ == '__main__':
    app.run('localhost', 4000)

拓展:

(1)深入provide_automatic_options参数

provide_automatic_options参数用于控制是否自动提供OPTIONS方法。

在HTTP协议中,OPTIONS方法用于获取指定URL支持的请求方法。Flask框架默认情况下会自动处理OPTIONS请求,并返回一个包含允许的请求方法的响应。

provide_automatic_options参数为True时,表示应用程序会自动提供OPTIONS方法的支持。如果请求的URL匹配到了一个路由规则,但是没有显式定义OPTIONS方法的处理函数,Flask会自动生成一个OPTIONS方法的处理函数来响应该请求。

provide_automatic_options参数为False时,表示应用程序不会自动提供OPTIONS方法的支持。即使请求的URL匹配到了一个路由规则,但是没有显式定义OPTIONS方法的处理函数,Flask也不会自动生成OPTIONS方法的处理函数。这意味着如果客户端发送了一个OPTIONS请求,而且没有相应的处理函数来处理该请求,Flask将返回一个405 Method Not Allowed的响应。

通过设置provide_automatic_options参数,开发者可以灵活地控制应用程序是否自动提供OPTIONS方法的支持,以满足具体需求。

(2)methods |= required_methods的作用

methods |= required_methods是在Flask中的路由定义过程中用于合并必需的方法(required methods)到可接受的方法(methods)集合的操作。

在Flask中,可以通过将请求方法作为装饰器参数传递给路由函数来指定允许的请求方法。例如:

@app.route('/', methods=['GET', 'POST'])
def index():
    # 处理GET和POST请求
    pass

在上述示例中,路由函数index()被定义为只接受GET和POST请求。但有时,可能还需要处理其他方法,例如OPTIONS或PUT等。这就是required_methods的作用。

required_methods是一个集合,包含了一些应该始终添加到可接受的方法集合中的方法。这些方法通常是特定于应用程序的、必须支持的方法。

通过使用按位或(OR)运算符|=,将required_methods集合合并到methods集合中,并将结果赋值给methods。这样就确保了methods集合中包含了所有必需的方法。

例如,如果methods集合已经包含了[‘GET’],而required_methods集合包含了[‘OPTIONS’],那么执行methods |= required_methods后,methods集合将变为[‘GET’, ‘OPTIONS’]。

这样做的目的是确保路由能够处理所有必需的请求方法,从而提供更全面的HTTP方法支持。

(3)深入self.view_functions

self.view_functions是一个字典,用于存储Flask应用程序中所有路由终点(endpoint)与对应视图函数(view function)之间的映射关系。

它是在Flask应用程序对象的初始化过程中创建的,并作为一个实例属性存在。self.view_functions字典的定义如下:

self.view_functions: Dict[str, Callable] = {}

这意味着self.view_functions是一个键值对形式的字典,其中键是路由的终点名称,值是对应的视图函数。具体来说,键是字符串类型,值是可调用对象(callable),通常是Python函数。

当使用@app.route()装饰器定义路由时,Flask框架会自动将路由终点和对应的视图函数添加到self.view_functions字典中。这样,在接收到请求时,Flask可以根据路由终点从字典中找到对应的视图函数,并执行相应的逻辑。

实战——如何使用self.view_functions字典:

from flask import Flask

app = Flask(__name__)


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


@app.route('/index')
def index():
    return 'index'


if __name__ == '__main__':
    print(app.view_functions)

运行就会输出app.view_functions字典的内容:

{
	'static': <function Flask.__init__.<locals>.<lambda> at 0x000001A3334258B0>, 
	'demo': <function demo at 0x000001A3334364C0>, 
	'index': <function index at 0x000001A333436550>
}

可以通过访问app.view_functions来查看和操作Flask应用程序中注册的视图函数,例如获取所有终点名称、获取对应的视图函数等。文章来源地址https://www.toymoban.com/news/detail-558733.html

到了这里,关于(五)Flask之深入剖析路由源码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python框架之Flask入门和视图

    需要安装 Pycharm专业版 Python后端的2个主流框架 Flask 轻量级框架 Django 重型框架 Flask是一个基于Python实现的web开发微框架 官方文档:https://flask.palletsprojects.com/ 中文文档:https://dormousehole.readthedocs.io/ Flask是一个基于MVC设计模式的Web后端框架 MVC: M: Model 数据模型 V: View 界面 C:

    2024年02月06日
    浏览(33)
  • Python web实战 | 用 Flask 框架快速构建 Web 应用【实战】

    Python web 开发已经有了相当长的历史,从最早的 CGI 脚本到现在的全栈 Web 框架,现在已经成为了一种非常流行的方式。 Python 最早被用于 Web 开发是在 1995 年(90年代早期),当时使用 CGI 脚本编写动态 Web 页面。2004 年 Django 框架发布,它是一个高度模块化的框架,提供了许多

    2024年02月07日
    浏览(42)
  • Python光速入门 - Flask轻量级框架

            FlASK是一个轻量级的WSGI Web应用程序框架,Flask的核心包括Werkzeug工具箱和Jinja2模板引擎,它没有默认使用的数据库或窗体验证工具,这意味着用户可以根据自己的需求选择不同的数据库和验证工具。Flask的设计理念是保持核心简单,同时提供强大的扩展性,用户

    2024年03月14日
    浏览(40)
  • 初识Flask:Python轻量级Web框架入门教程

    Flask是一个用Python编写的轻量级Web应用框架。由于其“微”性质,Flask在提供核心服务的同时,仍然提供了许多扩展的可能性。在这篇文章中,我们将从最基础开始,学习如何使用Flask构建一个Web应用。 首先,你需要安装Flask库。使用pip进行安装是最简单的方式: 接着,我们来

    2024年02月14日
    浏览(44)
  • 基于 Python 的 Flask 框架开发的在线电影网站系统(附完整源码)

    今天我给大家分享的是基于Python的Flask框架开发的在线电影网站系统,大家平时需要哪个方面的项目都可以在每篇文章的下面留言,我后续会在公众号分享出来。 该项目为基于Python的Flask框架搭建的在线电影网站 项目介绍:网站前端采用HTML5编写,使用Bootstrap前端开发框架,后

    2024年02月07日
    浏览(41)
  • python高校舆情分析系统+可视化+情感分析 舆情分析+Flask框架(源码+文档)✅

    毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏) 毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总 🍅 感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。

    2024年02月01日
    浏览(35)
  • python Web开发 flask轻量级Web框架实战项目--学生管理系统

     上次发的一篇文章,有很多朋友私信我要后面的部分,那咱们就今天来一起学习一下吧,因为我的数据库这门课选中的课题是学生管理系统,所以今天就以这个课题为例子,从0到1去实现一个管理系统。数据库设计部分我会专门出一个博客的,敬请期待吧~~~ 介如很多朋友问

    2024年02月16日
    浏览(39)
  • 【附源码】基于flask框架的音乐专辑微信小程序 (python+mysql+论文)

    本系统(程序+源码)带文档lw万字以上   文末可获取本课题的源码和程序 选题背景: 在当今数字化时代,音乐作为一种重要的文化娱乐形式,已经深入人们的日常生活。随着互联网技术的快速发展,人们获取和分享音乐的方式也发生了巨大的变化。从传统的实体唱片到在线

    2024年04月25日
    浏览(33)
  • 毕业设计:python租房数据分析可视化系统+爬虫+Flask框架 大数据(附源码)✅

    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌感兴趣的可以先收藏起来,点赞、关注不迷路✌ 毕业设计:2023-2024年计算机毕业设计1000套(建议收藏)

    2024年01月23日
    浏览(36)
  • 毕业设计:python医疗数据分析可视化系统 医疗大数据 Flask框架 用户画像(源码)✅

    博主介绍:✌全网粉丝10W+,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久,选择我们就是选择放心、选择安心毕业✌感兴趣的可以先收藏起来,点赞、关注不迷路✌ 毕业设计:2023-2024年计算机毕业设计1000套(建议收藏)

    2024年04月16日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包