python|web应用框架|使用类装饰器注册路由

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: python|web应用框架|使用类装饰器注册路由

之前我们介绍了如何利用WSGI写一个简单的web应用框架。写出来之后,项目虽然能用,如果还没有看过上述文章的,建议先看下,以便做到承上启下:

python|写一个简单的web应用框架: juejin.cn/post/722635…


本文的python环境为:

image.png

在上述文章中,我们调用框架后,在定义路由的时候,使用的代码如下:

myWeb.Routes("/index",index)
myWeb.Routes("/123",d345)


如上代码,虽然能够完成工作,但是不够美观。我们想要我们的框架像flask那样,使用装饰器来定义路由,例如,这样:

routes(path="/123",methods="post")
def helloWold(r):
    return (200,"hello world")

这样的话,就不用再额外使用Routes将路由和函数绑定了。



类装饰器应该怎么写?

要实现上述功能,需要用到类装饰器,这里需要先简单阐述一下如何使用类装饰器,我们之前使用的都是函数来做的装饰器。


再探类私有方法

类装饰器需要重写__init__方法和__call__方法。如之前文章所述,前者在实例化类为对象的时候进行调用,而后则则是在调用对象的时候才会调用。


这里写一个简单的案例,来复习一下__init____call__方法。


image.png


上述代码,就写了一个类testClass,在该类中,我们定义了__init__方法和__call__方法,我们为每隔一方法打印了一条输出语句。


最后我们定义了一个类testClass实例test1。而后再运行该实例。

运行后效果如下:

image.png

通过输出,我们可以发现,在将类实例化为对象的时候,就启动了__init__方法,而__call__方法,则需要调用实例的时候,才能运行。



装饰器调用方法


我们目前看到的装饰器调用方法,都是在函数前面定义@而后跟上装饰器名称,如果有参数的话,会跟上参数,但是这都是语法糖的效果。


看一个装饰器例子:

image.png


上述代码,我们定义了一个装饰器decorator,该装饰器仅是在调用函数前后打印输出一些内容。而后再test3函数上面,使用@来调用装饰器。最后执行函数test3

代码执行效果如下:

image.png

上述代码中,所谓的语法糖就是@后面的语句,下面我们将不是用语法糖,来实现一下这个操作。

image.png

该代码,我们不使用python语法糖,所以我们定义手动将函数test3作为参数,传入decorator装饰器中,装饰器返回wrapper函数,我们将使用f来接收,最后我们通过调用f函数来实现装饰器的调用。

代码执行结果如下:

image.png

还有一种情况是,如果装饰器带参数了,这个时候需要在装饰器外部在定义一层函数,用于接收参数,例如代码如下:

image.png

上述代码,使用了re来接收装饰器本身的参数,其他的和上述一致,我们执行代码,结果如下:

image.png

这里之所以强调装饰器,是因为我们想写函数式的装饰器来接收参数。



类作为装饰器

类善用私有方法,也可以实现装饰器的效果,例如:

image.png

上述代码,我们使用类的私有方法,来定义装饰器,上述代码如果不是语法糖的话,那么下面这段代码,应该如何调用呢?

@decorator
def test3():
    print("哈哈哈")


如果不是语法糖的话,是不是应该是

f  = decorator(test3)
f()


所以,需要使用__init__方法来接收函数,而在call方法中,我们直接写代码即可,中间需要调用从__init__传过去的方法。

代码执行后,结果如下:

image.png

如果装饰器需要传参,传参这个动作就是类+(),就会执行底层方法__call__,所以,参数需要在__init__中接收,而函数需要在__call__中去接收,代码如下:

image.png


这个代码写的相对复杂,这里解析一下,我们将上述装饰器拆分为普通函数,代码如下:

f = decorator(x=3,y=5)
f1 = f(test3)
print(f1(3,5))

好了,现在看起来是不是感觉好多了呢?我们调用decorator(x=3,y=5),该代码是将类初始化为对象,所以需要在__init__方法中去解析传过来的xy,而f(test3),则是对象的调用了,需要需要去__call__找到传入的函数。这个时候__call__里面又是一个闭包函数,将闭包函数返回后,得到f1,最后我们执行f1函数,就先当于执行了wraper()函数,如果需要传参的话,我们直接写入参数即可,因为在闭包函数wrapper中,我们也传参了的: *args,**kwargs


所以上述代码,使用@语法糖装饰器的话,执行结果如下:

image.png


如何注册路由


有了上面类装饰器的铺垫,再来写解析路由的话,就非常容易了,我们首先要确定,装饰器中应该传入什么样的值?作为绑定路由信息来说,我们最需要知道的是路由值和请求方法,所以我们想定义绑定函数类似于如下:

routes(path="/123",methods="post")
def helloWold(r):
    return (200,"hello world")

那作为routes装饰器,我们需要在其__init__方法中接收pathmethods的值,在__call__方法中获取函数值。


当注册路由之后,我们直接将其存储到字典中,整个注册路由就写完了。


我们可以查看代码:

image.png


如上代码,我们先定义了2个字典:mapGetRoutemapPostRoute来存储GET请求和POST请求的信息。


当进行函数注册的时候,需要获取装饰器传上来的pathmethods,而后根据其请求方法,将数据存储到对应的字典中,若是指定的ALL,则2个都存储。


最后只需要在启动函数application中,对客户端请求进行解析,如果存在注册路由的函数,就直接获取存储的函数值调用就完事了。

image.png


上述代码,我们会对每一个请求进行判断,而后取出相应字典中的函数,并且执行后,将结果返回回去。注意,这里还是有问题的,若请求没有在路由字典中,则func的值为None,就会抛错,我们可以定义一个万金油路由,若匹配不到,就重定向到该路由函数中去,向客户端返回404即可。


改善后的框架代码,我也放到了gitee上: gitee.com/pdudo/golea…

启动wsgi应用,我们直接使用的wsgiref,代码案例如下:

gitee.com/pdudo/golea…



总结


这篇文章,我们介绍了类作为装饰器应该如何调用,最后我们通过该特性,复写了一下我们框架的路由解析,让其路由函数和其他普通函数分开好看一点 。类写装饰器,其实是善用了其私有函数__init____call__。这里要注意一下,装饰器带参数和不带参数对应的类装饰器,都是不同的。





相关文章
|
21天前
|
安全 前端开发 数据库
Python 语言结合 Flask 框架来实现一个基础的代购商品管理、用户下单等功能的简易系统
这是一个使用 Python 和 Flask 框架实现的简易代购系统示例,涵盖商品管理、用户注册登录、订单创建及查看等功能。通过 SQLAlchemy 进行数据库操作,支持添加商品、展示详情、库存管理等。用户可注册登录并下单,系统会检查库存并记录订单。此代码仅为参考,实际应用需进一步完善,如增强安全性、集成支付接口、优化界面等。
|
10天前
|
JSON 安全 中间件
Python Web 框架 FastAPI
FastAPI 是一个现代的 Python Web 框架,专为快速构建 API 和在线应用而设计。它凭借速度、简单性和开发人员友好的特性迅速走红。FastAPI 支持自动文档生成、类型提示、数据验证、异步操作和依赖注入等功能,极大提升了开发效率并减少了错误。安装简单,使用 pip 安装 FastAPI 和 uvicorn 即可开始开发。其优点包括高性能、自动数据验证和身份验证支持,但也存在学习曲线和社区资源相对较少的缺点。
51 15
|
7天前
|
关系型数据库 API 数据库
Python流行orm框架对比
Python中有多个流行的ORM框架,如SQLAlchemy、Django ORM、Peewee、Tortoise ORM、Pony ORM、SQLModel和GINO。每个框架各有特点,适用于不同的项目需求。SQLAlchemy功能强大且灵活,适合复杂项目;Django ORM与Django框架无缝集成,易用性强;Peewee轻量级且简单,适合小型项目;Tortoise ORM专为异步框架设计;Pony ORM查询语法直观;SQLModel结合Pydantic,适合FastAPI;GINO则适合异步环境开发。初学者推荐使用Django ORM或Peewee,因其易学易用。
|
10天前
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
49 7
|
1月前
|
JSON 数据可视化 测试技术
python+requests接口自动化框架的实现
通过以上步骤,我们构建了一个基本的Python+Requests接口自动化测试框架。这个框架具有良好的扩展性,可以根据实际需求进行功能扩展和优化。它不仅能提高测试效率,还能保证接口的稳定性和可靠性,为软件质量提供有力保障。
78 7
|
1月前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
88 2
|
1月前
|
敏捷开发 测试技术 持续交付
自动化测试之美:从零开始搭建你的Python测试框架
在软件开发的马拉松赛道上,自动化测试是那个能让你保持节奏、避免跌宕起伏的神奇小助手。本文将带你走进自动化测试的世界,用Python这把钥匙,解锁高效、可靠的测试框架之门。你将学会如何步步为营,构建属于自己的测试庇护所,让代码质量成为晨跑时清新的空气,而不是雾霾中的忧虑。让我们一起摆脱手动测试的繁琐枷锁,拥抱自动化带来的自由吧!
|
2月前
|
开发者 Docker Python
从零开始:使用Docker容器化你的Python Web应用
从零开始:使用Docker容器化你的Python Web应用
78 1
|
2月前
|
JSON 前端开发 API
使用Python和Flask构建简易Web API
使用Python和Flask构建简易Web API
155 3
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
219 3