werkzeug/routing.py-Rule源码分析
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源码分析的更多相关文章
- JUnit源码分析 - 扩展 - 自定义Rule
JUnit Rule简述 Rule是JUnit 4.7之后新加入的特性,有点类似于拦截器,可以在测试类或测试方法执行前后添加额外的处理,本质上是对@BeforeClass, @AfterClass, ...
- flask/app.py-add_url_rule源码分析
之前分析route方法的时候,可以看到中间会调用add_url_rule方法,add_url_rule方法和route方法一样属于Flask这个类的. add_url_rule方法主要用来连接url规 ...
- FastText总结,fastText 源码分析
文本分类单层网络就够了.非线性的问题用多层的. fasttext有一个有监督的模式,但是模型等同于cbow,只是target变成了label而不是word. fastText有两个可说的地方:1 在w ...
- Python 日志打印之logging.getLogger源码分析
日志打印之logging.getLogger源码分析 By:授客 QQ:1033553122 #实践环境 WIN 10 Python 3.6.5 #函数说明 logging.getLogger(nam ...
- illuminate/routing 源码分析之注册路由
我们知道,在 Laravel 世界里,外界传进来一个 Request 时,会被 Kernel 处理并返回给外界一个 Response.Kernel 在处理 Request 时,会调用 illumina ...
- OpenHarmony移植案例: build lite源码分析之hb命令__entry__.py
摘要:本文介绍了build lite 轻量级编译构建系统hb命令的源码,主要分析了_\entry__.py文件. 本文分享自华为云社区<移植案例与原理 - build lite源码分析 之 hb ...
- flask源码分析
本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...
- Flask系列之源码分析(一)
目录: 涉及知识点 Flask框架原理 简单示例 路由系统原理源码分析 请求流程简单源码分析 响应流程简单源码分析 session简单源码分析 涉及知识点 1.装饰器 闭包思想 def wapper( ...
- Flask源码分析二:路由内部实现原理
前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...
- Flask系列10-- Flask请求上下文源码分析
总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...
随机推荐
- Springboot项目mysql日期存储不匹配问题和在idea本地可以运行起来,但打包jar后运行报找不到mysql驱动的解决方案
修改pop.xml中scope的值,如果是具体版本号,修改为如下即可解决 <dependency> <groupId>mysql</groupId> <art ...
- Jmeter之__CSVRead随机读取变量
背景:当你需要从一些数据中随机的取值用的话可以用这个函数来实现__CSVRead __CSVRead函数用于对脚本进行参数化,当脚本中不同变量需要不同参数值时,可以考虑__CSVRead函数. _CS ...
- WebSocket始终保持连接的办法
在项目中,后台为了其实把处理结果主动推送个前端,因此使用了WebSocket. 但是问题来了,页面每跳转一次,socket都要重新关闭建立连接.这个资源消耗是很大的,而且线上环境随着并发量的增加会报错 ...
- linux非root用户安装nginx
先到官网http://nginx.org/en/download.html下载最新稳定版源码包,目前是1.16.1: 下完后通过rz上传至wlf用户soft目录下,退回上一级目录解压: $ cd so ...
- Django model中的save后的return
先给结论吧:在Django model的操作函数中,obj.save()后再执行return obj会返回obj的ID. 看例子: ... def create_session(self,bind_h ...
- 初步了解 Netty
精通并发与 Netty (一)如何使用 精通并发与 Netty Netty 是一个异步的,事件驱动的网络通信框架,用于高性能的基于协议的客户端和服务端的开发. 异步指的是会立即返回,并不知道到底发送过 ...
- (简单实用)Android支付宝商家收款语音播报
支付宝商家收款时,语音提示:支付宝收款xxx元,当时觉得这东西还挺有趣的,第一时间通知给商家,减少不必要的纠纷,节约时间成本,对商家对用户都挺好的. 在商家版有这样收款播报的功能,我觉得挺好的. 对列 ...
- mybatis xml动态语句写法
mapper.java: /** * @Description: 根据摄像机Id查询出入记录 * @Param: * name 姓名 * monitorId 布控ID * starttime 开始时间 ...
- Java注解-注解处理器、servlet3.0|乐字节
大家好,我是乐字节的小乐,上次给大家带来了Java注解-元数据.注解分类.内置注解和自定义注解|乐字节,这次接着往下讲注解处理器和servlet3.0 一.注解处理器 使用注解的过程中,很重要的一部分 ...
- 034 Android NavigationView和DrawerLayout实现抽屉式导航设计(侧边栏效果)
1.创建带侧滑效果的activity 右击,new---->activity---->选择NavgationDrawer Activity 2.xml文件布局 (1)activity_ma ...