开发者社区> 游客2silnuajy47wo> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

一日一技:在Python里面实现链式调用

简介: 一日一技:在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()



1.png


直接对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()


2.png


从图中可以看出,现在已经不会报错了。那么回到最开始的问题,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)


运行效果如下图所示:


3.png


在真正需要输出结果的时候,再使用这些缓存的条件,去数据库中查询结果即可。


请关注微信公众号【未闻Code】获取更多精彩文章。 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
舔狗至高境界,学会这个技巧让你从舔狗升华到海王【Python趣味爬虫】
舔狗至高境界,学会这个技巧让你从舔狗升华到海王
13 0
舔狗至高境界,学会这个技巧让你从舔狗升华到海王【Python趣味爬虫】
mport requests from lxml import etree ​ ​ smtp封装发信协议 import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart ​ ​ ​ ​ ​ 发送邮箱 ​ msg_from = '1641324821@qq.com' passwd = 'fdltqccdspvedegj' ​ tos = ['xxxxxxxxx@qq.com', 'xxxxxxxxx@qq.com', 'xxxxxxxxx@qq.com', '
19 0
舔狗至高境界,学会这个技巧让你从舔狗升华到海王【Python趣味爬虫】
舔狗至高境界,学会这个技巧让你从舔狗升华到海王【Python趣味爬虫】
13 0
Python学习笔记:通过python爬虫获取豆瓣电影Top250
之前学习了python中的一些语法,但未有一些实际的项目,这边在B站上找了一个爬虫小项目教程,此文章简单介绍如何爬取豆瓣电影Top250
296 0
【Python】从0开始写爬虫——豆瓣电影
1. 最近略忙。。java在搞soap,之前是用工具自动生成代码的。最近可能会写一个soap的java调用 2. 这个豆瓣电影的爬虫。扒信息的部分暂时先做到这了。扒到的信息如下 from scrapy import app import re header = { 'User-Agent': 'Mozilla/5.
1023 0
【Python】从0开始写爬虫——转身扒豆瓣电影
豆瓣就比较符合这个“明人不说暗话”的原则。所以我们扒豆瓣,不多说,直接上代码 from scrapy import app import re header = { 'User-Agent': 'Mozilla/5.
988 0
2个月精通Python爬虫——3大爬虫框架+6场实战+分布式爬虫,包教包会
阿里云大学在线工作坊上线,原理精讲+实操演练,让你真正掌握云计算、大数据技能。 在第一批上线的课程中,有一个Python爬虫的课程,畅销书《精通Python网络爬虫》作者韦玮,带你两个月从入门到精通。
6207 0
Python爬虫之多线程下载豆瓣Top250电影图片
爬虫项目介绍   本次爬虫项目将爬取豆瓣Top250电影的图片,其网址为:https://movie.douban.com/top250, 具体页面如下图所示:   本次爬虫项目将分别不使用多线程和使用多线程来完成,通过两者的对比,显示出多线程在爬虫项目中的巨大优势。
2313 0
80
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载