同一个 URL 同时能匹配好几条规则时,Flask 选哪一条?和写代码的先后顺序有关吗?这篇每种情形都用两种注册顺序各跑一遍。
/users/<name> 与 /users/me
注册顺序 A /users/me → fixed | /users/ann → dyn{'name': 'ann'}
注册顺序 B(倒过来) /users/me → fixed | /users/ann → dyn{'name': 'ann'}
两种顺序结果相同: True /<x>(string)与 /<int:x>
注册顺序 A /123 → int{'x': 123} | /abc → str{'x': 'abc'} | /-5 → str{'x': '-5'}
注册顺序 B(倒过来) /123 → int{'x': 123} | /abc → str{'x': 'abc'} | /-5 → str{'x': '-5'}
两种顺序结果相同: True
/files/<name> 与 /files/<path:p>
注册顺序 A /files/a → name{'name': 'a'} | /files/a/b → path{'p': 'a/b'}
注册顺序 B(倒过来) /files/a → name{'name': 'a'} | /files/a/b → path{'p': 'a/b'}
两种顺序结果相同: True /<a>/<b>、/<a>/x、/api/<b>
注册顺序 A /1/x → ax{'a': '1'} | /1/y → ab{'a': '1', 'b': 'y'} | /api/x → api_b{'b': 'x'} | /api/zz → api_b{'b': 'zz'}
注册顺序 B(倒过来) /1/x → ax{'a': '1'} | /1/y → ab{'a': '1', 'b': 'y'} | /api/x → api_b{'b': 'x'} | /api/zz → api_b{'b': 'zz'}
两种顺序结果相同: True 先注册 first、后注册 second → GET /dup: first
先注册 second、后注册 first → GET /dup: second GET /x → 200 'GET 端点'
POST /x → 200 'POST 端点'
PUT /x → 405 '<!doctype html>\n<htm'
DELETE /x → 405 '<!doctype html>\n<htm' iter_rules 顺序(按注册顺序,不排序): ['/users/<name>', '/users/me', '/<x>', '/<int:x>']
每条规则被拆成片段,每个片段有权重(取自私有属性 Rule._parts;权重越小优先级越高):
/users/<name> [静态 users [(0, -5)]] [动态 [100]]
/users/me [静态 users [(0, -5)]] [静态 me [(0, -2)]]
/<x> [动态 [100]]
/<int:x> [动态 [50]] url_map 的匹配器: StateMachineMatcher | merge_slashes = True
GET /users//me → 308 | Location = http://localhost/users/me