目的:为支持WSGI的网页框架添加路由功能
基础框架:
import time
def login():
return '这是登录页,当前时间:{}'.format(time.ctime())
def index():
return '这是主页,当前时间:{}'.format(time.ctime())
def application(env,start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK',[('Content-Type','text/html;charset=UTF-8')])
file_name = env['path_info']
if file_name == 'login.py':
return login()
elif file_name == 'index.py':
return index()
else:
return 'hello world!冬天来了的body'
其中fille_name 为浏览器访问的端口之后的地址例如 http://127.0.0.1:8080/login.py 中的 login.py
第一步:去掉 if 语句
思路: 将file_name和函数的引用放到字典中去,通过字典去访问
import time
def login():
return '这是登录页,当前时间:{}'.format(time.ctime())
def index():
return '这是主页,当前时间:{}'.format(time.ctime())
URL_FUNC_DICT ={
'login.py':login ,
'index.py':index
}
def application(env,start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK',[('Content-Type','text/html;charset=UTF-8')])
file_name = env['path_info']
func = URL_FUNC_DICT[file_name]
return func()
第二步:去掉手动写的字典,让程序自动写字典
思路:通过装饰器,完成字典的添加
import time
URL_FUNC_DICT =dict()
def route(url):
def set_func(func):
URL_FUNC_DICT[url] = func
def aaa(*args,**kwargs):
return func(*args,**kwargs)
return aaa
return set_func
@route('login.py')
def login():
return '这是登录页,当前时间:{}'.format(time.ctime())
@route('index.py')
def index():
return '这是主页,当前时间:{}'.format(time.ctime())
def application(env,start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK',[('Content-Type','text/html;charset=UTF-8')])
file_name = env['path_info']
func =URL_FUNC_DICT[file_name]
return func()
第三步:支持像 /add/151.py 或者 https://blog.csdn.net/m0_55415810 这种形式的url地址。
思路:使用正则表达式去匹配url ,然后返回固定的函数
import re
import time
def login():
return '这是登录页,当前时间:{}'.format(time.ctime())
def index():
return '这是主页,当前时间:{}'.format(time.ctime())
def add_founc():
return 'add OK'
URL_FUNC_DICT = {
r'login.py': login,
r'index.py': index,
r'add/\d+.py':add_founc
}
def application(env, start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
file_name = env['path_info']
print('file_name'+':'+file_name)
for url ,func in URL_FUNC_DICT.items():
ret= re.match(url,file_name)
if ret:
return func()
循环取 URL_FUNC_DICT 字典中的键值对,作为re.match 的参数,如果匹配成功,则返回匹配成功的正则表达式作为key,取对应的值(对应的函数),然后调用
即将字典中固定的键值对,变成不固定的键 对应 固定的值。
再将装饰器放入
import time,re
URL_FUNC_DICT =dict()
def route(url):
def set_func(func):
URL_FUNC_DICT[url] = func
def aaa(*args,**kwargs):
return func(*args,**kwargs)
return aaa
return set_func
@route(r'login.py')
def login():
return '这是登录页,当前时间:{}'.format(time.ctime())
@route(r'index.py')
def index():
return '这是主页,当前时间:{}'.format(time.ctime())
@route(r'add/\d+.py')
def add_func():
return 'add OK'
def application(env, start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
file_name = env['path_info']
print('file_name'+':'+file_name)
for url ,func in URL_FUNC_DICT.items():
ret= re.match(url,file_name)
if ret:
return func()
上面只是支持这个格式,但是访问的函数,是固定的,也就是没有传递参数,现在想要传递参数到函数中去
思路:利用正则的group, 生成匹配到的特定结果
import time,re
URL_FUNC_DICT =dict()
def route(url):
def set_func(func):
URL_FUNC_DICT[url] = func
def aaa(*args,**kwargs):
return func(*args,**kwargs)
return aaa
return set_func
@route(r'login.py')
def login(ret):
return '这是登录页,当前时间:{}'.format(time.ctime())
@route(r'index.py')
def index(ret):
return '这是主页,当前时间:{}'.format(time.ctime())
@route(r'add/(\d*).py')
def add_func(ret):
code=ret.group(1)
if code:
print('匹配结果:%s'%code)
return 'add OK 匹配结果 :%s'%code
def application(env, start_response):
# 调用传递过来的方法,返回响应状态码和头部信息
start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
file_name = env['path_info']
print('file_name'+':'+file_name)
for url ,func in URL_FUNC_DICT.items():
ret= re.match(url,file_name)
if ret:
return func(ret)
在application中,正则匹配到结果,不为空时,调用对应的函数,并将re.match正则表达式传递给函数,函数如果要用,则group 生成,不用,则不管