Python中如何实现链式调用
我们在使用Django的models查询数据库时,可以看到有这种写法:
form app.models import XXX
query = XXX.objects.all()
query = query.filter(name=123, age=456).filter(salary=999)
在这种写法里面,query对象有一个filter方法,这个方法的返回数据还可以继续调用filter方法,可以这样无限制地调用下去。
这种写法是怎么实现的呢?
如果我们直接写一个类的方法,看看能不能这样调用:
class Query:
def filter(self):
pass
query = Query()
query.filter().filter()
直接对query.filter()返回的结果再调用一次filter,就会导致报错了。这是因为在没有显式写return语句的时候,方法会返回None,而None对象是没有所谓的filter方法的。
那么什么东西有filter方法呢?显然我们的query对象有filter方法。那么如何让这个方法返回自身这个对象呢?
这个时候,我们就要看看我们在定义类方法的时候,总会写的的第一个参数self了。几乎每个类方法里面都会有它。大家只知道在类里面调用类方法的时候可以用self.xxx(),在调用类属性的时候可以用self.yy,那么有没有思考过,这个东西如果单独使用会怎么样呢?
实际上,self指的就是这个类实例化成一个对象以后,这个对象自身。而这个对象显然是有filter方法的。所以我们修改一下filter方法,让它返回self:
class Query:
def filter(self):
return self
query = Query()
query.filter().filter()
从图中可以看出,现在已经不会报错了。那么回到最开始的问题,Django里面的链式调用传入查询参数是如何实现的呢?
实际上这里涉及到一个惰性查询的问题。
当我们不停调用.filter()方法的时候,Django会把这些查询条件全部缓存起来,只有当我们需要获取结果,或者查询满足条件的数据有多少条时,它才会真正地连接数据库去查询。
所以我们这里要模拟这个环境,把查询条件缓存起来。
那么为了获取调用方法时传入的参数名,我们就要使用**kwargs参数。这个参数可以接受所有的key=value形式的参数:
class Query():
def __init__(self):
self.query_condition = {}
def filter(self, **kwargs):
self.query_condition.update(kwargs)
return self
query = Query()
a = query.filter(name='kingname').filter(age__gt=15, address='yyyyyy').filter(salary=99999)
print(query.query_condition)
运行效果如下图所示:
在真正需要输出结果的时候,再使用这些缓存的条件,去数据库中查询结果即可。
(资源库 www.zyku.net)
原文链接:https://mp.weixin.qq.com/s/LmTO6WL6stw3S5-WWJ6s6A
您可能感兴趣的文章
- 03-27Python API 邮件发送测试
- 03-27Python命令行如何运行文件
- 03-27Python 实现单向链表,和单向链表的反转
- 09-07Python2与Python3关于字符串编码处理的差别总结
- 05-20520使用Python实现“我爱你”表白
- 05-10python调用API接口实现登录短信验证
- 05-10python对接ihuyi实现短信验证码发送
- 06-05CentOS 6.5下安装Python 3.5.2(与Python2并存)
- 02-20使用notepad运行php,python的图文设置方法
- 02-20Notepad++如何安装Python插件?
- 03-17鸿蒙系统限制广告跟踪方法
- 07-05Linux ifconfig命令
- 12-09火车头采集器代码过滤方法
- 01-11Quillio日记-Quillio日记应用软件功能
- 07-24jQuery Migrate 插件用法
- 09-11qq音乐如何分享歌单
- 02-23DedeCms时间格式汇总
- 01-12快马办公excel表格-快马办公excel表格
- 05-25windows modules installer worker是
- 12-26西牛招聘-西牛招聘应用软件功能介绍
最近更新
阅读排行
猜你喜欢
- 09-22小米mix4在哪里查看未接电话
- 12-30瑞云服务云-瑞云服务云应用软件功能介
- 02-28WordPress获取当前日志的所有附件的方
- 04-21oppofindx3开启红包助手方法
- 01-14我的铃声-我的铃声应用软件功能介绍
- 12-31创豆连线编程-创豆连线编程应用软件功
- 01-13dedecms搜索页面不能使用arclist等标
- 12-29苹果手机设置回原壁纸方法介绍
- 05-07vivox60pro开启双击亮屏功能教程
- 09-27小米MIX4怎么投屏