今天主要讲一下werkzeug中的routing模块。这个模块是werkzeug中的重点模块,Flask中的路由相关的操作使用的都是这个模块

routing模块的用法

在讲解模块的源码之前,先讲讲这个模块怎么用。
创建Map()对象:

>>> m = Map([
...     # Static URLs
...     Rule('/', endpoint='static/index'),
...     Rule('/about', endpoint='static/about'),
...     Rule('/help', endpoint='static/help'),
...     # Knowledge Base
...     Subdomain('kb', [
...         Rule('/', endpoint='kb/index'),
...         Rule('/browse/', endpoint='kb/browse'),
...         Rule('/browse/<int:id>/', endpoint='kb/browse'),
...         Rule('/browse/<int:id>/<int:page>', endpoint='kb/browse')
...     ])
... ], default_subdomain='www')

我们可以看到,一个Map中以列表的形式包含多个Rule. 示例里面还有个Subdomain,除了Subdomain名外,它里面以列表的形式包含多个Rule,如果没有Subdomain,后面的default_subdomain可以省略(default_subdomain适配于除了Subdomain之外的Rule部分)
在创建了Map的实例后,我们可以为每个Subdomain创建URL适配器

>>> c = m.bind('example.com')
>>> c.build("kb/browse", dict(id=42))   #如果url有参数,使用dict()里面填参数名和值
'http://kb.example.com/browse/42/'
>>> c.build("kb/browse", dict())        #build接受的参数是endpoint,返回url地址
'http://kb.example.com/browse/'
>>> c.build("kb/browse", dict(id=42, page=3))
'http://kb.example.com/browse/42/3'
>>> c.build("static/about")
'/about'
>>> c.build("static/index", force_external=True)
'http://www.example.com/'>>> c = m.bind('example.com', subdomain='kb')
>>> c.build("static/about")
'http://www.example.com/about'

部分源码分析

routing模块中有个RuleFactory类,提供了get_rules()工厂方法,该方法的设计目的是使得URL重用. 所有继承该类的类必须实现该方法
比如Subdomain类:

class Subdomain(RuleFactory):def __init__(self, subdomain, rules):self.subdomain = subdomainself.rules = rulesdef get_rules(self, map):for rulefactory in self.rules:for rule in rulefactory.get_rules(map):rule = rule.empty()rule.subdomain = self.subdomainyield rule

在该类中get_rules方法是一个生成器,调用一次返回一个subdomain中的rule,且该Rule未绑定.
同理还有Submount,EndpointPrefix类,源码差不多,就不细讲了。只说下怎么用:
Submount的用法:

url_map = Map([Rule('/', endpoint='index'),Submount('/blog', [Rule('/', endpoint='blog/index'),Rule('/entry/<entry_slug>', endpoint='blog/show')])])

把submount中第一个元素(路径)跟在原路径后,里面的Rule均以这个路径为挂载点
这里当访问'blog/entry/<entry_slug>'就会找到'blog/show'这个endpoint;当访问'blog'就会找到'blog/index'这个endpoint

EndpointPrefix的用法:

url_map = Map([Rule('/', endpoint='index'),EndpointPrefix('blog/', [Submount('/blog', [Rule('/', endpoint='index'),Rule('/entry/<entry_slug>', endpoint='show')])])])

和上一个示例等效,只不过是提取出了所有endpoint中相同的前缀放在前面

Rule类

在该类的实例中最重要的就是存储了URL地址。以下是它的构造方法的头部:

def __init__(self, string, defaults=None, subdomain=None, methods=None,build_only=False, endpoint=None, strict_slashes=None,redirect_to=None, alias=False, host=None)

在该类中,实现了bind方法,源码如下:

def bind(self, map, rebind=False):if self.map is not None and not rebind:raise RuntimeError('url rule %r already bound to map %r' %(self, self.map))self.map = mapif self.strict_slashes is None:self.strict_slashes = map.strict_slashesif self.subdomain is None:self.subdomain = map.default_subdomainself.compile()

该方法的作用就是把Rule的实例绑定到一个Map实例上去

Map类

在该类的实例中,存储了很多个Rule类的实例,同时还有部分配置参数。以下是它的构造方法的头部:

def __init__(self, rules=None, default_subdomain='', charset='utf-8',strict_slashes=True, redirect_defaults=True,converters=None, sort_parameters=False, sort_key=None,encoding_errors='replace', host_matching=False)

对照本文中开头的部分,可以发现rules参数是一个列表,该列表中包含了多个Rule的实例
在该类中实现了几个重要的方法:

  • add()方法:它的作用是把一个Rule的实例添加到该Map实例中,并绑定。源码很简单:
def add(self, rulefactory):for rule in rulefactory.get_rules(self):   #获得rule实例rule.bind(self)   #绑定该实例(源码见上面Rule类中的bind方法)#在Map的_rules列表中加入该Rule实例,_rules用来装Map初始化函数中rules参数传进的Rulesself._rules.append(rule)   self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)self._remap = True
  • bind()方法:返回一个MapAdapter类的实例,该类的作用是用来做URL的匹配。bind的头部为:
bind(self, server_name, script_name=None, subdomain=None,url_scheme='http', default_method='GET', path_info=None,query_args=None)

MapAdapter类

该类用来做URL匹配。
dispatcher()方法:该方法的作用是,传入path_info,该方法会使用match()方法找到对应的endpoint和相关参数,然后再把这个endpoint作为参数传入view_func视图函数中,返回一个view_func对象. 源码如下

def dispatch(self, view_func, path_info=None, method=None,catch_http_exceptions=False):try:try:endpoint, args = self.match(path_info, method)  #获得endpoint和所需参数except RequestRedirect as e:return ereturn view_func(endpoint, args)except HTTPException as e:if catch_http_exceptions:return eraise

match()方法:该方法的作用是,传入path_infomethod,该方法会返回对应的endpoint和路径包含的参数,比如:

    >>> m = Map([...     Rule('/', endpoint='index'),...     Rule('/downloads/', endpoint='downloads/index'),...     Rule('/downloads/<int:id>', endpoint='downloads/show')... ])>>> urls = m.bind("example.com", "/")  #urls是MapAdapter对象>>> urls.match("/", "GET")('index', {})>>> urls.match("/downloads/42")('downloads/show', {'id': 42})

build()方法:该方法与match()对应,传入endpoint和对应参数,返回path_info. 用法如下

    >>> m = Map([...     Rule('/', endpoint='index'),...     Rule('/downloads/', endpoint='downloads/index'),...     Rule('/downloads/<int:id>', endpoint='downloads/show')... ])>>> urls = m.bind("example.com", "/")>>> urls.build("index", {})'/'>>> urls.build("downloads/show", {'id': 42})'/downloads/42'

转载于:https://www.cnblogs.com/eric-nirnava/p/werkzeug4.html

Werkzeug源码阅读笔记(四)相关推荐

  1. werkzeug源码阅读笔记(二) 下

    wsgi.py----第二部分 pop_path_info()函数 先测试一下这个函数的作用: >>> from werkzeug.wsgi import pop_path_info ...

  2. 代码分析:NASM源码阅读笔记

    NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...

  3. 【Flink】Flink 源码阅读笔记(15)- Flink SQL 整体执行框架

    1.概述 转载:Flink 源码阅读笔记(15)- Flink SQL 整体执行框架 在数据处理领域,无论是实时数据处理还是离线数据处理,使用 SQL 简化开发将会是未来的整体发展趋势.尽管 SQL ...

  4. HashMap源码阅读笔记

    HashMap是Java编程中常用的集合框架之一. 利用idea得到的类的继承关系图可以发现,HashMap继承了抽象类AbstractMap,并实现了Map接口(对于Serializable和Clo ...

  5. Live555源码阅读笔记(一):源码介绍文档 及 源码目录结构

    目录 一.Live555介绍 1.Live555项目介绍 2.官网及帮助文档介绍 二.源码目录结构 1.UsageEnvironment 2.BasicUsageEnvironment 3.group ...

  6. LinkedList源码阅读笔记

    LinkedList源码阅读笔记 初始化 无参的 public LinkedList() {} 初始化的同时添加一个Collection public LinkedList(Collection< ...

  7. syzkaller 源码阅读笔记1(syz-extract syz-sysgen)

    文章目录 1. syz-extract 1-0 总结 1-1. `main()` 1-2 `archList()` - `1-1 (3)` 获取架构 name list 1-3 `createArch ...

  8. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  9. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

最新文章

  1. 查看安装的cuda和cudnn的版本号
  2. 《Spring Cloud与Docker微服务架构实战》配套代码
  3. 感受亚马逊:“抠门”的巨无霸电商如何炼成
  4. VTK:图片之PickPixel
  5. 第12章 坚持一百秒(《C和C++游戏趣味编程》教学视频)
  6. JavaScript继承详解(三)
  7. springboot + mybatis 学英语网、背单词网站
  8. 【变废为宝】电信IPTV中兴zxv10 b860Av1.1
  9. oppo手机解锁_OPPO手机忘记解锁密码怎么办 解锁手机密码
  10. sd卡启动分区的制作--使用fdisk 工具
  11. IOS 音乐播放器
  12. PNAS | 朱永官院士团队单细胞拉曼结合靶向宏基因组揭示土壤活性抗生素耐药组...
  13. A Self-paced Multiple-instance Learning Framework for Co-saliency Detection文章阅读
  14. 赵小楼《天道》《遥远的救世主》深度解析(82)有信无证是谓魔,有信有证是谓佛。无无明,无忧恐惧,尘归尘土归土,一往无前,无可阻挡。
  15. 2021杭电多校第3场_HDU6975_Forgiving Matching
  16. 艾司博讯:拼多多直通车自动调价要不要开启
  17. 浏览器跳不同 不同页面 php,利用js根据不同浏览器自动跳转不同页面
  18. CUDA编程(一):GPU计算与CUDA编程简介
  19. Python爬虫小结(转)
  20. HTML6(无序列表,有序列表和自定义列表)

热门文章

  1. 机器视觉之医学诊断应用
  2. SAP MM 进销存报表优化小记
  3. OBYC PRY PRV
  4. 盘点丨那些顶级的AI机器人“大脑”
  5. 行业观察 | 机器人Ameca挣脱「灵魂」枷锁觉醒?
  6. 麦肯锡季刊 | 人工智能的发展与障碍
  7. 邬贺铨院士:认识工业互联网
  8. 一文看懂谷歌的AI芯片布局,边缘端TPU将大发神威
  9. 英特尔反驳质疑:芯片供应充足、10nm量产没问题
  10. 互联网如何“升级”制造业?《“人工智能+制造”产业发展研究报告》发布