Rule类主要用来定义和表示一个URL的模式。主要定义了一些关键字参数,用来改变url的行为。例如:这个url可以接收的请求方法,url的子域名,默认路径,端点名称,是否强制有斜杠在末尾等等

在最开始使用route()传递的option参数,最后都是传给了Rule这个类来处理的

class Rule(RuleFactory):
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):
if not string.startswith('/'):
raise ValueError('urls must start with a leading slash')
self.rule = string
self.is_leaf = not string.endswith('/') self.map = None
self.strict_slashes = strict_slashes
self.subdomain = subdomain
self.host = host
self.defaults = defaults
self.build_only = build_only
self.alias = alias
if methods is None:
self.methods = None
else:
if isinstance(methods, str):
raise TypeError('param `methods` should be `Iterable[str]`, not `str`')
self.methods = set([x.upper() for x in methods])
if 'HEAD' not in self.methods and 'GET' in self.methods:
self.methods.add('HEAD')
self.endpoint = endpoint
self.redirect_to = redirect_to if defaults:
self.arguments = set(map(str, defaults))
else:
self.arguments = set()
self._trace = self._converters = self._regex = self._argument_weights = None

源代码

参数解析:

  • string:一个有含有占位符的url路径(<converter(arguments):name>), converter是可选的(converter定义在Map里面),默认是字符串
  • defaults:可选项。在同一个endpoint下的一个字典格式的默认规则,如果你访问某个url的时候,这个url存在default配置,则会显示defaluts对用的url路径 例如:
 url_map = Map([
Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),
Rule('/all/page/<int:page>', endpoint='all_entries')
])
# 当用户访问``http://example.com/all/page/1`` h将会重定向到``http://example.com/all/``.
  • subdomain:用来定义这个rule的子域名规则的一个字符串。默认是disable的,用法如下
url_map = Map([
Rule('/', subdomain='<username>', endpoint='user/homepage'),
Rule('/stats', subdomain='<username>', endpoint='user/stats')
])
  • methods:定义允许访问的方法。默认只允许get方法。在0.6.1版本中,会自动添加HEAD如果存在GET请求的话
  • bulid_only:True, 只创建url,而不会被匹配。一般用于静态文件的路径创建,不需要WSGI application处理的情况下
  • endpoint:这个url的端点名称,可以是任何类型。最好的选择是使用字符串表示,
  • strict_slashes:是否严格要求URL后面的斜杠。为这个URL重写Map里面的strict_slashes配置
  • redirect_to:重定向到其他地址。可以是一个字符串(其他url路径),也可以是一个可调用的对西对象。例如:
def foo_with_slug(adapter, id):
# ask the database for the slug for the old id. this of
# course has nothing to do with werkzeug.
return 'foo/' + Foo.get_slug_for_id(id) url_map = Map([
Rule('/foo/<slug>', endpoint='foo'),
Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'), # 重定向到上面定义的路径
Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug) # 重定向到foo_with_slug函数
])
  • alias:在同一个endpoint里面为rule serves定义一个别名
  • host:为整个host提供匹配规则。如果设置了host,则subdomain会是disabled状态

函数体解析:

    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):
# 判断url路径是否是斜线开头
if not string.startswith('/'):
# 抛出异常:urls必须以斜线开头
raise ValueError('urls must start with a leading slash')
self.rule = string
self.is_leaf = not string.endswith('/') self.map = None
self.strict_slashes = strict_slashes
self.subdomain = subdomain
self.host = host
self.defaults = defaults
self.build_only = build_only
self.alias = alias
# 对methods参数的判断
if methods is None:
self.methods = None
else:
if isinstance(methods, str):
raise TypeError('param `methods` should be `Iterable[str]`, not `str`')
self.methods = set([x.upper() for x in methods])
# 如果没有HEAD和有GET的时候,把HEAD添加到methods里面
if 'HEAD' not in self.methods and 'GET' in self.methods:
self.methods.add('HEAD')
self.endpoint = endpoint
self.redirect_to = redirect_to if defaults:
# 通过map对象以及str函数,取出defaulte中的每一个键,并设置成字符串格式。最终保存为set格式:{'abc'}
self.arguments = set(map(str, defaults))
else:
self.arguments = set()
self._trace = self._converters = self._regex = self._argument_weights = None

在Map对象的add方法中调用了Rule对象的get_rules方法

def get_rules(self, map):
yield self

在Map对象的app方法中调用了Rule类的bind方法

这个方法主要用来绑定路由规则到map,并基于路由规则信息创建正则表达式

     def bind(self, map, rebind=False):
# 判断这个rule的map属性是否已经被绑定过了map值
if self.map is not None and not rebind:
raise RuntimeError('url rule %r already bound to map %r' %
(self, self.map))
# 把Map的对象赋值给self.map
self.map = map
# 判断属性,如果Rule对象中没有,则使用Map类中的
if self.strict_slashes is None:
self.strict_slashes = map.strict_slashes
if self.subdomain is None:
self.subdomain = map.default_subdomain
# 调用Rule类的compile方法
self.compile()

bind方法最后调用了Rule类的compile方法

这个方法主要用来编译和存储正则表达式

werkzeug/routing.py-Rule源码分析的更多相关文章

  1. JUnit源码分析 - 扩展 - 自定义Rule

    JUnit Rule简述 Rule是JUnit 4.7之后新加入的特性,有点类似于拦截器,可以在测试类或测试方法执行前后添加额外的处理,本质上是对@BeforeClass, @AfterClass, ...

  2. flask/app.py-add_url_rule源码分析

    之前分析route方法的时候,可以看到中间会调用add_url_rule方法,add_url_rule方法和route方法一样属于Flask这个类的. add_url_rule方法主要用来连接url规 ...

  3. FastText总结,fastText 源码分析

    文本分类单层网络就够了.非线性的问题用多层的. fasttext有一个有监督的模式,但是模型等同于cbow,只是target变成了label而不是word. fastText有两个可说的地方:1 在w ...

  4. Python 日志打印之logging.getLogger源码分析

    日志打印之logging.getLogger源码分析 By:授客 QQ:1033553122 #实践环境 WIN 10 Python 3.6.5 #函数说明 logging.getLogger(nam ...

  5. illuminate/routing 源码分析之注册路由

    我们知道,在 Laravel 世界里,外界传进来一个 Request 时,会被 Kernel 处理并返回给外界一个 Response.Kernel 在处理 Request 时,会调用 illumina ...

  6. OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py

    摘要:本文介绍了build lite 轻量级编译构建系统hb命令的源码,主要分析了_\entry__.py文件. 本文分享自华为云社区<移植案例与原理 - build lite源码分析 之 hb ...

  7. flask源码分析

    本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...

  8. Flask系列之源码分析(一)

    目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...

  9. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  10. Flask系列10-- Flask请求上下文源码分析

    总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...

随机推荐

  1. springboot+jwt完成登录认证

    本demo用于测试jwt,通过登录验证通过后,使用jwt生成token,然后在请求header中携带token完成访问用户列表信息. 准备工作: 1. 实体类SysUser.java package ...

  2. [原]Arcgis arcmap修改图元配色

    感谢南师大的“深爱”提供的帮助 1.选择识别工具,点击海洋,确定海洋色块的color index为255 2.右键tif选择属性 3.选择分页栏中的符号化(Symbology) 4.找到对应的Labe ...

  3. flutte的第一个hello world程序

    用命令行创建项目: flutter create flutterdemo VSCode或者AS连接手机后 输入 flutter run 编译后就可以将默认的代码显示在手机上了 开始写hello wor ...

  4. stl中map的四种插入方法总结

    stl中map的四种插入方法总结方法一:pair例:map<int, string> mp;mp.insert(pair<int,string>(1,"aaaaa&q ...

  5. .NET Core入门程序

    易百教程 https://www.yiibai.com/dotnet_core/dotnet_core_getting_started.html

  6. linux部署php网页

    liunx环境下运行php和传统的Java web程序不一样.我直接放在tomcat下竟然不行. 安装了php的一些环境,还是访问不了,原因是不支持https访问.没办法,还是得用tomcat,同时我 ...

  7. ios开发将截图保存到相册

    - (void)loadImageFinished:(UIImage *)image { UIImageWriteToSavedPhotosAlbum(image, self, @selector(i ...

  8. Day2作业:购物商城

    ReadMe: 注意事项: 1.本程序需要提前安装prettytable模块,在商品展示时使用了prettytable 2.数据库使用json模块,有中文数据,在mac系统上编写,运行没有出现问题,在 ...

  9. SAP RFC和BAPI

    RFC和BAPI都是SAP提供的接口技术.RFC全称Remote Function Call,就是允许远程调用的函数模块. BAPI则是基于RFC的新技术,全称Business Application ...

  10. Delphi 中使用计算出的字段

    在很多情况下,我们需要的数据与数据库中其它字段的数据相关,例如订单的金额为数量与单价的乘积.在应用程序中,若要在显示订单具体条目的同时显示金额,通常要创建一个字段,在显示该字段之前先进行乘法运算,将金 ...