python库源码分析_python库学习:records库源码分析

介绍

最近看到了kennethreitz的介绍(谁说程序员不是潜力股?让这位世界前五名的天才程序员来颠覆你三观!),实在太励志了!然后看了一下github仓库,看到几个比较短的项目,觉得挺好玩的,就记录一下分析结果。

records这个项目一共才415行代码,核心代码才一两百行,主要基于sqlalchemy和tablib两个库,这么少的代码就实现了对数据库提供python化查找和分析。只需要输入sql语句就可以把结果包成对象返回,极大的方便了用户。其实我个人觉得还可以更简洁一点,在query接口中,只提供了table的名称,连sql都不用写。

分析sqlalchemy:python的ORM框架

tablib:kennethreitz的另一个项目,主要是把数据处理为XLS, CSV, JSON, YAML格式返回。

项目一共有三个核心的class,Database,RecordCollection,Record。我们就以这三个class讲开。

Record储存每条数据的详情;RecordCollection储存query的查找结果,也就是Record的集合;Database数据库的操作集合。

形象的来说:RecordCollection就是拉皮条的,手里有很多的Record,来源自Database,客户就是我们。。。。

Database

对数据库的连接和操作的封装,也就是sqlalchemy的操作。环境变量

records不仅可以传db_url,而且也提供环境变量DATABASE_URL。

2. 上下文管理协议

包含的方法__enter__()和__exit__(),__enter__()是在语句体执行之前运行的,__exit__()是在语句体结束后运行的。最常用的就是with()的用法。在records里面,__enter__()返回了整个对象,__exit__()主要是把db连接关掉。使用上下文之后,可以使连接能及时关掉。

# 上下文的例子

class Student(object):

def __enter__(self):

# 进入

print('coming')

return 'student'

def __exit__(self, exc_type, exc_val, exc_tb):

# 离开

print('byebye')

def func():

return Student()

with func() as a:

print(a)

# result

>>> python a.py

coming

student

byebye

3. __repr__()

重构了__repr__()方法,在里面加入了db是否连接。刚开始定义的open变量作用就只是用在这里显示。

4. query()

query()就是Database里面最核心的一个方法了,对数据库进行查找,把结果存储到Record对象中,并把Record集合存储到RecordCollection,并返回。

5. query_file()

读取文件中的sql语句,在最后也是使用query()方法。

6. transaction

在records里面也是有事务操作。

RecordCollection

正如注释所讲: A set of excellent Records from a query.生成器

在Database中的query()方法中,如果你传入了fetchall为True的话,就会把生成器全部执行完,这个时候pending就为False。

所以pending变量的作用就是用来了解生成器的值有没有全部取出来。

__next__()和__iter__()两个方法主要就是实现了整个生成器,利用生成器极大的节省了内存开销。在生成器中还加入了_all_rows这个变量,在每次迭代,都会把值存入里面,然后每次取值,都会从里面拿。相当于缓存了_all_rows里面。

2. 导出数据

RecordCollection和Record都有export,一个是导出整个表,一个是导出某一条。用的就是tablib,能导出各种格式。

Record多格式输出

可以用row.user_email, row['user_email'], row[3]

使用__getitem__()和__getattr__()进行配合,如果是row[3]的话,__getitem__()能直接抓取到,如果是str的话,__getattr__()抓取到然后传给__getitem__()解析。

包括提供的get()方法,其实也是__getitem__()解析的。

所有通过[]取数据都会走到__getitem__()方法。

2. 导出数据

Record也是使用的tablib导出数据,跟RecordCollection类似。

3. __slots__

如果有大量的计算和循环的话,可以使用__slots__,能节省很大的内存消耗。由于keys和values需要经常访问,用了__slots__可以减少访问速度。

命令行工具

利用docopt来创建命令行工具。docopt的具体用法可以参考另外一篇文章python库学习: 命令行参数解析库docopt。

总结

records这个库充分利用了python的特殊方法,如__getitem__(),__getattr__(),__slots__()等。并且在整个架构上面设计也是十分合理,非常适合阅读源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值