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

第1步:

class Flask(_PackageBoundObject):
def route(self, rule, **options):
def decorator(f): #f = hello_world
       #1.1获取别名
endpoint = options.pop('endpoint', None)
       #1.2
self.add_url_rule(rule, endpoint, f, **options)
return f
return decorator

第1.2步:

class Flask(_PackageBoundObject):
def add_url_rule(self, rule, endpoint=None, view_func=None, **options):
#1.2.1如果别名是None,执行_endpoint_from_view_func函数
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
     #1.2.2 给endpoint赋值
options['endpoint'] = endpoint
     #1.2.3 获取允许的请求方法
methods = options.pop('methods', None)
     #1.2.4如果方法为None
if methods is None:
       #默认为GET
methods = getattr(view_func, 'methods', None) or ('GET',)
     #1.2.5如果方法是字符串,抛出异常: 必须是methods=["POST"]这样可迭代的
if isinstance(methods, string_types):
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
     #1.2.6把方法变成大写
methods = set(item.upper() for item in methods)
     #1.2.7把匹配url和允许请求的方法封装到了Rule的一个对象中
rule = self.url_rule_class(rule, methods=methods, **options)
     #self.url_rule_class = Rul
     #1.2.8
self.url_map.add(rule)
      #self.url_map = Map()
if view_func is not None:
       #1.2.9 此步完成后: {"别名":被装饰的函数名}
self.view_functions[endpoint] = view_func

第1.2.1步:

def _endpoint_from_view_func(view_func):
#返回被装饰的函数名
return view_func.__name__

第1.2.8步:

class Map(object):
def add(self, rulefactory):
#1.2.8.1
for rule in rulefactory.get_rules(self):
       #1.2.8.2 Rule对象进行re正则绑定
rule.bind(self)
       #1.2.8.3 添加到self._rules列表中,此时列表中就有了url
self._rules.append(rule)
       #1.2.8.4 此步完成后: {"别名":url}
self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)

第1.2.8.1步:

class Rule(RuleFactory):
  def get_rules(self, map):
yield self
   #返回Rule对

第1.2.8.2步:

class Rule(RuleFactory):
  def bind(self, map, rebind=False):
     #1.2.8.2.1
self.compile()

第1.2.8.2.1步: 看不懂,猜里面是把url进行了re正则处理

class Rule(RuleFactory):
def compile(self):
if self.map.host_matching:
domain_rule = self.host or ''
else:
domain_rule = self.subdomain or '' self._trace = []
self._converters = {}
self._static_weights = []
self._argument_weights = []
regex_parts = [] def _build_regex(rule):
index = 0
for converter, arguments, variable in parse_rule(rule):
if converter is None:
regex_parts.append(re.escape(variable))
self._trace.append((False, variable))
for part in variable.split('/'):
if part:
self._static_weights.append((index, -len(part)))
else:
if arguments:
c_args, c_kwargs = parse_converter_args(arguments)
else:
c_args = ()
c_kwargs = {}
convobj = self.get_converter(
variable, converter, c_args, c_kwargs)
regex_parts.append('(?P<%s>%s)' % (variable, convobj.regex))
self._converters[variable] = convobj
self._trace.append((True, variable))
self._argument_weights.append(convobj.weight)
self.arguments.add(str(variable))
index = index + 1 _build_regex(domain_rule)
regex_parts.append('\\|')
self._trace.append((False, '|'))
_build_regex(self.is_leaf and self.rule or self.rule.rstrip('/'))
if not self.is_leaf:
self._trace.append((False, '/')) if self.build_only:
return
regex = r'^%s%s$' % (
u''.join(regex_parts),
(not self.is_leaf or not self.strict_slashes) and
'(?<!/)(?P<__suffix__>/?)' or ''
)
self._regex = re.compile(regex, re.UNICODE)

到此为止:

路由规则列表里新增了一条绑定正则的rule ;{"别名":rule} ;{"别名":被装饰的函数名}

python-flask-路由匹配源码分析的更多相关文章

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

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

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

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

  3. Flask之wtforms源码分析

    一.wtforms源码流程 1.实例化流程分析 # 源码流程 1. 执行type的 __call__ 方法,读取字段到静态字段 cls._unbound_fields 中: meta类读取到cls._ ...

  4. Flask系列之源码分析(二)

    应用技术点 python之__setattr__ python之threading.local python之偏函数 flask源码上下文管理 1.综述过程 将请求对象压入栈 1.请求进入 __cal ...

  5. Python线程池ThreadPoolExecutor源码分析

    在学习concurrent库时遇到了一些问题,后来搞清楚了,这里记录一下 先看个例子: import time from concurrent.futures import ThreadPoolExe ...

  6. flask请求上下文源码分析

    一.什么是上下文 每一段程序都有很多外部变量,只有像add这种简单的函数才是没有外部变量的,一旦你的一段程序有了外部变量,这段程序就不完整了,不能独立运行,你为了使他们能运行,就要给所有的外部变量一个 ...

  7. python之epoll服务器源码分析

    #!/usr/bin/env python # -*- coding: utf8 -*- import socket, select EOL1 = b'/r/n' EOL2 = b'/r/n/r/n' ...

  8. 基于python的ardrone control源码分析与心得

    这里有一段python代码,可用于操控ardrone 2.0.实验室曾经借鉴用过,并添加了部分功能.如今复习一下,顺便理理python的相关知识点. #!/usr/bin/env python # A ...

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

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

随机推荐

  1. P1829 [国家集训队]Crash的数字表格 / JZPTAB

    推式子太快乐啦!虽然我好蠢而且dummy和maomao好巨(划掉) 思路 莫比乌斯反演的题目 首先这题有\(O(\sqrt n)\)的做法但是我没写咕咕咕 然后就是爆推一波式子 \[ \sum_{i= ...

  2. .net core 问题:413 Request Entity Too Large nginx

    https://stackoverflow.com/questions/38698350/increase-upload-file-size-in-asp-net-core The other ans ...

  3. js旋转V字俄罗斯方块

    实现效果如图,也就是一个图像的旋转.注意,旋转后的文字是相对应的,而且文字还是立起的.第一次点击时显示,第二次点击时开始旋转.下面是我做这个效果的记录,方法这么差,我也就不说什么了. 先上HTML/C ...

  4. 【译】第5节---Code First约定

    原文:http://www.entityframeworktutorial.net/code-first/code-first-conventions.aspx 我们在上一节中已经看到了EF Code ...

  5. 【Java】【线程】

    /* 栗子 通过Runnable接口实现简历线程实例 */ class Dog implements Runnable{ //重写run函数 public void run(){ int times ...

  6. JavaSE 字符串和正则表达式

    根据不懂的自己整理一下,跟着老师进度刷一遍课本,记录琐碎不懂知识 1.StringTokenizer类 String[] mess= {"整数部分","小数部分" ...

  7. C#双缓冲代码

    private void Form1_Load(object sender, EventArgs e) { //在窗体加载的时候 解决窗体闪烁问题 //将图像绘制到缓冲区减少闪烁 this.SetSt ...

  8. java添加templates模板,httpServlet模板改写

    为了提高开发效率,通常将一些常用模板添加到快捷键,方法: window-prefrerences-java-editor-templates 代码复制进去apply应用即可 package com.l ...

  9. django认证系统 Authentication

    Django自带一个用户认证系统,用于处理用户账户.群组.许可和基于cookie的用户会话. Django的认证系统包含了身份验证和权限管理两部分.简单地说,身份验证用于核实某个用户是否合法,权限管理 ...

  10. DOM结构及优化

    1.DOM树中三种常见的DOM节点: 1>元素节点:上图中<a>,<h1>等都是元素节点,即标签 2>文本节点:向用户展示的内容,如...中的"文档标题& ...