werkzeug/routing.py-Map()源码解析

Map类主要用来存储所有的url规则和一些配置参数的。其中有一些配置的值只存储在Map实例里,因为这些值影响着所有的规则,还有一些其他的默认规则可以被重写。

通过之前分析的add_url_rule源码可以知道,是在add_url_rule方法里调用的Map类,并调用了类的add方法,同时传递了rule对象

 1 # Map()类__init__源码
 2 
 3 class Map(object):
 4     # 定义一个字典格式的默认转换器
 5     default_converters = ImmutableDict(DEFAULT_CONVERTERS)
 6 
 7     def __init__(self, rules=None, default_subdomain='', charset='utf-8',
 8                  strict_slashes=True, redirect_defaults=True,
 9                  converters=None, sort_parameters=False, sort_key=None,
10                  encoding_errors='replace', host_matching=False):
11         self._rules = []
12         self._rules_by_endpoint = {}
13         self._remap = True
14         self._remap_lock = Lock()
15 
16         self.default_subdomain = default_subdomain
17         self.charset = charset
18         self.encoding_errors = encoding_errors
19         self.strict_slashes = strict_slashes
20         self.redirect_defaults = redirect_defaults
21         self.host_matching = host_matching
22 
23         # 由于之前设置了default_converters为不可变类型,所以需要copy一份
24         self.converters = self.default_converters.copy()
25         # 如果传递了converters参数,则更新到self.converters里面
26         if converters:
27             self.converters.update(converters)
28 
29         self.sort_parameters = sort_parameters
30         self.sort_key = sort_key
31 
32         # 遍历rules,并调用add方法把每一个遍历对象传递进去
33         # 实例化的时候这个rules是空的,所以第二次调用是在解析self.url_map.add(rule)的时候
34         # add方法详情请看下面的解析
35         for rulefactory in rules or ():
36             self.add(rulefactory)

参数解析:

  •     default_converters = ImmutableDict(DEFAULT_CONVERTERS)
 1 # 定义一个字典格式的默认转换器
 2 # ImmutableDict是werkzeug/datastructures.py文件里面的一个类,用来把一个字典变成不可变格式
 3 # DEFAULT_CONVERTERS变量是定义在routing.py文件里的一个全局变量
 4 DEFAULT_CONVERTERS = {
 5     'default':          UnicodeConverter,
 6     'string':           UnicodeConverter,
 7     'any':              AnyConverter,
 8     'path':             PathConverter,
 9     'int':              IntegerConverter,
10     'float':            FloatConverter,
11     'uuid':             UUIDConverter,
12 }

  • rules:url规则
  • default_subdomain:默认的子域名
  • charset:编码格式,默认"utf-8"
  • strict_slashes:是否严格要求URL末尾的斜线
  • redirect_defaults:重定向到默认的url
  • converters:转换器,如果重新定义了,会重写原始的
  • sort_parameters:是否排序(url_encode可以看到更详细的信息)
  • sort_key:是否关键字
  • encoding_errors:用与解码的错误方法
  • host_mathcing:如果设置为True,则会通过host去匹配,而不会使用subdomain
备注:sort_parameters 和 sort_key是在0.5版本增加的, encoding_errors和host_matching是在0.7版本增加的

 

Map类里面的add方法

主要是用来添加新的规则或则工厂函数到map中,并且绑定它。要求这个规则没有被绑定给其他的map
self.url_map.add(rule)
传递的rule是个Rule对象,
 1 # app()源码
 2 
 3 def add(self, rulefactory):
 4     # 调用Rule类的get_rules方法,返回值为yield self
 5     for rule in rulefactory.get_rules(self):
 6         # 调用Rule类的bind方法
 7         rule.bind(self)
 8         # 添加rule对象到self._rules里面
 9         # url路径,方法,视图函数
10         # [<Rule '/static/<filename>' (HEAD, GET, OPTIONS) -> static>, <Rule '<test4>|/text3' (POST, OPTIONS) -> test>]
11         self._rules.append(rule)
12         # 根据endpoint的规则
13         # {'static': [<Rule '/static/<filename>' (GET, OPTIONS, HEAD) -> static>], 'test123': [<Rule '<test4>|/text3' (POST, OPTIONS) -> test123>]}
14         self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule)
15         self._remap = True

 

posted @ 2018-01-21 18:57  eric_yi  阅读(636)  评论(0编辑  收藏  举报