昨天我们已经已经修改了web
路由注册,将其从函数方式注册,修改为类装饰器注册,如果你还没有看过此前那篇文章,建议你先看下,以便做到承上启下:
python|web应用框架|使用类装饰器注册路由:juejin.cn/post/722879…
今天我们将继续对该框架进行路由添加正则表达式。
在介绍之前,我们首先要介绍一下Get
获取资源的时候,有如下几种传参方式:
key...value
的形式,将参数放到url
问号?
后面,如: http://127.0.0.1/userInfo?name=pdudo
url
中以路径参数的方式传递,例如: http://127.0.0.1/userInfo/pdudo/info
。key...value
的形式存储的,当然也可以自定义存放请求参数。上述的第二种以路径参数的方式传参,就是我们这边文章所描述的点。
为什么需要这样做呢?
假设我们现在正在写一个功能,他需要返回传上来的用户信息,接口为: /userInfo/userid/infos
,其中userid
是动态的,所以接口可以是/userInfo/c12345/infos
,也可以是/userInfo/d33456/infos
等等。
如果是这种情况,我们应该怎么样样定义路由呢? 是在项目中给每个人都定义一个路由信息么?
很显然不是的,如果这个时候,注册的路由恰恰好是正则的,可以获取客户端传上来的参数,例如:/userInfo/pdudo/info
,函数将会获取pdudo
,这样不是很好么?
这就需要用到正则了。
由于我们此前已经写好了定义静态路由的相关方法,所以我们在定义动态路由的时候,最好加一个识别参数,告诉框架,这个路由是静态的 还是 动态的。
由于是动态路由,所以在路由url
中,有些值肯定是动态的,如何在区别于静态的值和动态的值呢? 在该框架中,我们将动态值用大括号括起来,比如: /userInfo/{userID}/infos
,其中userID
是动态的,可以是任何值组成,但是/userInfo
和/infos
必须是静态的,而且先后顺序也是固定的。
所以说,我们可以约束一下,在定义动态路由的时候,需要告诉框架,我这个是动态路由,以及动态url
。
所以我们准备将动态路由定义规划如下:
@myWeb.routes(path="/jobs/{jobID}/startd",methods="post",regular=True)
def startJobs(r,cData):
print("cData: " ,cData)
上述代码,是我们即将完善功能后的代码案例,其中regular
为True
代表该路由是动态的,path
的值为/jobs/{jobID}/startd
,其中jobID
也是动态的,可以被任何值代替。
最后是函数将接收2个参数,r
的值代表wsgi
中的environ
信息。 而cData
则代表从客户端上报的值,即:jobID
的替代值。
如上我们已经约束好了一个动态路由的添加规则,那么我们如何注册动态路由呢?
首先肯定的是,动态路由肯定不能和静态路由放在一起,所以我们定义了新的字典用于存放动态路由的信息,如:
mapGetRegularRouting = {}
mapPostRegularRouting = {}
而后则是我们需要将注册的路由信息转换为正则表达式,这里举个例子:
我们注册的路由是这样的: /jobs/{jobID}/startd
,我们需要将其转换为正则表达式,正则表达式的值是这样的: ^/jobs/(.*?)/startd$
。
关于这段正则表达式,它的含义是 匹配以/jobs/
开头和/startd
结尾的字符串,并且将匹配到的信息(.*
的值)存储到元组中。
注意这里.*
后面的问号?
代表不启用贪婪匹配,也就是最小化匹配。
现在的问题是,如何将{jobsID}
给转换为(.*?)
呢? 在python
中,可以使用re.sub
进行替换操作,我们可以使用如下语句,将{jobsID}
给替换为(.*?)
,代码如下:
import re
print(re.sub("{.*?}","(.*?)","/jobs/{jobID}/startd"))
如上代码执行的结果为:
最后将该路由信息存储到上述定义好的字典中即可,代码片段如下:
reFindall = re.compile(r"{(.*?)}")
reSubAll = re.compile(r"{.*?}")
parameter = re.findall(reFindall,self.path)
reText = re.sub(reSubAll,"(.*?)",self.path)
reText = f"{reText}$"
regular = {
"original": self.path,
"reText": reText,
"parameter": parameter,
"func": func
}
# ...
if self.re:
mapPostRegularRouting[regular["reText"]] = regular
至此,我们的动态路由就已经注册好了。
相比于注册动态路由,当客户端请求来了之后,匹配动态路由会很麻烦,因为没有请求报文不是告诉你,这是动态路由还是静态路由,所以说,匹配动态路由很麻烦。
我们匹配动态路由想到的时候笨办法,即: 先匹配静态路由,若静态路由匹配不到,则再匹配动态路由,若动态路由都匹配不到的话,则选用默认路由。
匹配静态路由和动态路由,前面篇章已经介绍过了,所以这里不再赘述,这里就介绍如何匹配动态路由。
所谓的动态路由规则匹配,实际上就是拿着客户端上传的url
,挨个对我们已有的正则表达式做轮训,若匹配成功则退出循环,若匹配失败,最后就返回一个默认路由即可,匹配正则表达式代码如下:
for key in RegularRouting.keys():
if re.match(key, path):
isRegular = True
collText = re.findall(key, path)
func = RegularRouting[key]["func"]
break
else:
func = Route["/*"]
关于
myWeb.py
由于很长,有100多行,不好截图,也不好纯复制代码了,所以放到了gitee
上面:gitee.com/pdudo/golea…
我们简单写几个demo
测试一下web
框架,代码如下:
import myWeb
import wsgiref.simple_server
@myWeb.routes(path="/ip",methods="all")
def indx(r):
print(r["REMOTE_ADDR"])
return (200,r["REMOTE_ADDR"])
@myWeb.routes(path="/hello/{name}",methods="get",regular=True)
def helloWold(r,cData):
name = cData[0]
return (200,"hello %s" % (name))
def main():
s = wsgiref.simple_server.make_server('', 8888, myWeb.application)
s.serve_forever()
if __name__ == '__main__':
main()
上述代码,我们首先引入了myWeb
和wsgiref
模块,前置是我们自己写的,后则是一个满足wsgi
服务器框架,在代码中,我们定义了2个路由信息,一个是静态路由,一个是动态路由,其中静态路由的函数是indx
,路由信息是/ip
,匹配的客户端请求方法为get
或者post
,该方法主要返回ip
地址。
动态路由的函数则是helloWold
,它将匹配到以/hello/
为首的路由信息,匹配客户端请求方法为get
,还函数主要获取用户发送的动态值,并且以hello
等返回给客户端。
在主函数中,我们启动一个简单的wsgi
服务器,入口为myWeb
的application
方法 。
代码运行效果如下:
我们分别使用get
和post
方法,请求本地/ip
路由,可见都回复回来了,而后我们访问/hello/pdudo
和/hello/juejin
,他们也分别回复了hello pdudo
和hello juejin
。
本篇文件介绍了将此前的web
框架,路由修改为正则表达式形式,具体添加方式为: 在进行路由注册的时候,将其路由信息转换为正则表达式,而在进行路由匹配的时候,先匹配静态服务器,若静态服务器没有,再进行正则匹配,若正则匹配依然不行,则返回最后的默认页面。
当下这个大数据时代不掌握一门编程语言怎么跟的上时代呢?当下最火的编程语言Python前景一片光明!如果你也想跟上时代提升自己那么请看一下.
感兴趣的小伙伴,赠送全套Python学习资料,包含面试题、简历资料等具体看下方。
CSDN大礼包:全网最全《Python学习资料》免费赠送!(安全链接,放心点击)
一、Python所有方向的学习路线
Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
工具都帮大家整理好了,安装就可直接上手!
三、最新Python学习笔记
当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集
观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例
纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、面试宝典
简历模板
CSDN大礼包:全网最全《Python学习资料》免费赠送!(安全链接,放心点击)
若有侵权,请联系删除