接着上一篇flask是如何启动的,这篇主要讲路由映射是何时生成的,以及生成过程是如何的,如果有写的不太准确的地方,麻烦帮忙指正,谢谢,希望大家一起进步。
文章目录
- 简单示例
- 源码部分
- app.route源码阅读
- 装饰器使用相关
- app.add_url_rule源码
- Map.add源码
- Rule.bind源码
- Rule.compile源码
- Rule._compile_builder源码
- Tips
- 增加对路由理解的辅助源码
我们都知道,flask的路由匹配是基于python特有语法装饰器实现的,如下代码所示
- 那么@app.route(’/’)是如何实现url和试图函数之间的映射的,我们来看下源码
装饰器使用相关
0x00
要想看懂这个,得了解点装饰器相关的用法,这里简单介绍一下,这里主要是说针对函数的装饰器
首先大家必须要了解的是,装饰器函数是在被加载时就已经运行了,而不是等到函数确定调用到使用装饰器的地方才开始执行装饰器,举个例子说
0x01
结构最简单的装饰器(不带参数)
0x02
和Flask.route相关的复杂一点的装饰器(带参数)
- 了解了这两种常见的装饰器模型,其实就可以理解flask中的route函数就是其中第二种的套用,不同的是,只写到了第二层,返回要装饰的的函数,只有客户端访问相应的路由,才会调用到视图函数
- 我们可以看出decorator函数中只调用了一个核心函数add_url_rule(),我们接下来看下这个函数都干了什么
还是先看源码长什么样子
注释解释的比较详细了,将装饰器和这个函数的关系解释的明明白白
- endpoint是路由名称,就是你在后端设置路由函数的名字,通过这个名字可以直接找得到相应的路由函数,默认为路由函数的名字
- methods表示请求方式,默认为get
- 上述两个参数都是为调用werkzeug的路由库Routing.Rule使用的
- url_map.add(Rule(rule, **options))
- 可以看的出来这是往路由映射中添加Rule对象
- Rule是werkzeug的路由库的类,这里面映射着端点名,路由以及视图函数的映射关系
- 接下来又要看add方法干什么活了
这是Map的add方法,所以这里的self是指map对象,而for循环中的rule是Rule对象,所以rule.bind是要从Rule中寻找bind方法去研究,为什么这里说一下,因为Map类中也有个add方法,别看错了
绑定路由到url_map函数
对路由进行规则的正则匹配,并生成最终的完整的路由映射
这个函数是将路由映射完成的核心函数,比较复杂,可以打断点走着看
为了加深理解,建议用如下代码打断点,走一走我重点标注的这几个函数
将url路由映射关系添加整理为小demo如下
到此结束,总结来看,从启动读到脚本中装饰器就开始就把把和响应的函数方法对应起来,从而应对客户端对于不同路由的响应