Lunar, 一个Python网络框架的实现

本文介绍了作者实现的Python网络框架Lunar,类似Django和Flask。文章详细阐述了Lunar的组成部分,包括ORM框架、模板引擎、Router和WSGI的实现。ORM框架实现了类与数据库表的映射,模板引擎处理模板语言编译,Router负责请求转发,而WSGI是Python网络应用的基础接口。作者分享了实现过程中的思考和挑战,以及对框架未来重构的计划。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前前后后,大概两个月的时间,lunar这个项目终于达到了一个很高的完整度。

Lunar是一个Python语言的网络框架,类似于Django,Flask,Tornado等当下流行的web framework。最初有这个想法是在大二下学期,当时接触Python web编程有一段时间。最早接触Python web编程或许是在大一下?自觉当时编程还没有入门,第一个接触的web框架是Django,很庞大的框架,当时很low逼的去看那本Django Book的中文译本,翻译的其实很不错了,只是进度会落后于当前的版本,所以在跑example的时候会有一些问题,Django的庞大规模给我留下了很大的心理阴影,所以在之后,对于涉世未深的Pythoner,我可能都不会推荐Django作为第一个Python的网络框架来学习。

整个框架的挑战还是非常大的。核心的几个组件(模板引擎,ORM框架,请求和应答的处理)还是有一些难度,但是经过一步步的分析和编码还是能够完成功能。项目受Flask非常大的影响,最初作为造轮子的初衷,几乎完整的使用了Flask和SQLAlchemy的API接口。

项目同样开源在Github上: https://github.com/jasonlvhit/lunar

也可以通过pip直接安装:

$ pip install lunar

这里我大概的记述一下lunar整个项目的各个组件的设计和实现。

ORM framework

首先是ORM。

python圈子里面还是有很多很著名的orm框架,SQLAlchemy,peewee, pony orm各有特色,SQLAlchemy和peewee都已經是很成熟的框架,大量的被应用在商业环境中。回到Lunar,既然是造轮子,何不造个彻底,于是便撸了一个orm框架出来。

在ORM框架中,我们使用类的定义来表示数据库中的表结构,使用类方法避免繁琐的SQL语句,一个ORM类定义类似于下面这段代码:

pyclass Post(db.Model):

    __tablename__ = 'post'

    id = database.PrimaryKeyField()
    title = database.CharField(100)
    content = database.TextField()
    pub_date = database.DateField()

    author_id = database.ForeignKeyField('author')
    tags = database.ManyToManyField(rel='post_tag_re', to_table='tag')

    def __repr__(self):
        return '<Post %s>' % self.title

上面这段代码取自Lunar框架的ORM测试和一个博客的example,这段代码定义了一个Post类,代表了数据库中的一张表,类中的一系列属性分别对应着表中的列数据。

一个peewee或者SQLAlchemy类似语法的一个ORM框架语句类似下面这样:

py    p = Post.get(id=1)

返回的结果是Post类的实例,这个实例,p.id返回的不是一个PrimaryKeyField,而是一个int类型值,其他的与数据库关联的类属性也是同样。

orm框架本质上是sql语句或者数据库模式(schema)和python对象之间的转换器或者翻译器,这有些类似于编译器结构。

在这里,Post是我们创建的一个orm类,post拥有若干数据操作方法,通过调用类似这样的更加人性化或者直观的api,代替传统的sql语句和对象映射。orm框架将语句翻译为sql语句,执行,并在最后将语句转换为post类的实例。

可能从这个角度看来,实现orm框架并不是什么tough的任务,让我们用上面提到的这个例子来看

py p = Post.get(id=1)

这条语句翻译成的sql语句为

select * from post where id=1;

可以看到的是,get方法会使用一个select语句,翻译程序将post类的表名和条件分别组合到select语句中,嗅觉灵敏的pythoner会发现这是一个典型的Post类的classmethod,直接通过类来调用这个方法,我们可以快速的写出这个函数的伪代码:

pyclass Model(Meta):

    ...

    @classmethod
    def get(cls, *args, **kwargs):
        # get method only supposes to be used by querying by id.
        # UserModel.get(id=2)
        # return a single instance.
        sql = "select * from %s"
        if kwargs:
            sql += "where %s"
        rs
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值