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

前前后后,大概两个月的时间,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
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答这个问题。以下是一个简单的Python万年历代码,包含节日和节气: ```python import calendar import datetime import requests import json def get_lunar_date(year, month, day): url = f"http://api.xlongwei.com/service/datetime/convert.json?d={year}-{month}-{day}T00:00:00" response = requests.get(url) data = json.loads(response.text) lunar_year = data["lunarYear"] lunar_month = data["lunarMonth"] lunar_day = data["lunarDay"] lunar_date = f"{lunar_year}年{lunar_month}月{lunar_day}" return lunar_date def print_calendar(year, month): cal = calendar.monthcalendar(year, month) for week in cal: for day in week: if day == 0: print(" ", end="") else: today = datetime.date(year, month, day) lunar_date = get_lunar_date(year, month, day) print(f"{day:^2}({lunar_date:<2})", end="") festivals = get_festivals(today) if festivals: print(" " + festivals, end="") solar_terms = get_solar_terms(today) if solar_terms: print(" " + solar_terms, end="") print(" ", end="") print() def get_festivals(date): festivals = {"0101": "元旦节", "0401": "愚人节", "0501": "劳动节", "0601": "儿童节", "1001": "国庆节", "1224": "平安夜", "1225": "圣诞节"} month = f"{date.month:02d}" day = f"{date.day:02d}" date_str = month + day return festivals.get(date_str) def get_solar_terms(date): url = f"http://www.sojson.com/api/lunar/solar-term/{date.year}" response = requests.get(url) data = json.loads(response.text) solar_terms = data.get(str(date.month)).get(str(date.day)) return solar_terms if __name__ == "__main__": today = datetime.date.today() year = input("请输入年份: ") or today.year month = input("请输入月份: ") or today.month year = int(year) month = int(month) print(f"{year}年{month}月日历") print("-" * 40) print("日 一 二 三 四 五 六 ") print("-" * 40) print_calendar(year, month) ``` 这个万年历代码使用了Python内置的calendar模块来生成日历,并使用了第三方API获取农历信息和节气信息。代码中的get_festivals函数可以返回节日名称,get_solar_terms函数可以返回节气名称。可以根据需要修改或添加节日和节气。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值