如果我编写这样的代码,我可以将对象实例上的方法调用链接在一起:
class ChainClassTest(object):
def order_by(self, *args, **kwargs):
print("I'm in order_by")
return self
def filter_by(self, *args, **kwargs):
print("I'm in filter_by")
return self
def get_list(self, *args, **kwargs):
print("I'm in get_list")
return self
if __name__ == "__main__":
cct = ChainClassTest()
cct.get_list().filter_by().order_by()
但是我希望能够让get_list()
调用根据order_by
设置的值执行一些操作。当然,在执行order_by
的时候get_list
已经完成了执行,所以我不能这样做。或者我可以吗?你知道吗
我考虑过使用get_list
、filter_by
、order_by
和其他类似的方法来更新一堆函数调用,然后在最后执行它们。。。当然,除了没有办法知道你已经走到了尽头。你知道吗
这将允许这种情况发生
cct.get_list().filter_by().order_by()
cct.now_actually_do_it()
其中now_actually_do_it
消耗了前一行代码创建的函数堆栈,但我真的希望能够在一行中完成这项工作。你知道吗
编辑1:为了清楚起见,我只提到了now_actually_do_it
作为如何完成的指示,但我真的不想这样做。你知道吗
在这种情况下,您希望有一个链式调用类型,但是不能返回
self
,因为order_by()
不会作用于filter_by()
正在创建的过滤结果集,而是作用于原始的cct
对象。你知道吗相反,每个方法都应该返回一个结果集,该结果集还包含用于添加过滤等的方法
另一方面,Python已经为其中大部分内置了:
因此,这样做的唯一原因是,如果您实际构建的查询被延迟到对库的调用或服务调用,就像ORM一样。在这种情况下,您应该构建一个包含过滤和排序命令的对象链并返回它,然后在调用时解析和执行该链。你知道吗
在上述函数中返回
self
在任何情况下都没有什么用处。你知道吗当然,除非您在每个调用中实际修改self,但如果您这样做,您的链式调用API将很混乱。改变自我意志 表示对象保留的状态不是对象的一部分,而是调用的一部分。例如,您可以让
.filter_by()
在对象上设置一个过滤器,由.get_list()
使用。但在创建新的.get_list()
之前,必须重置该筛选器,否则该筛选器仍将处于活动状态。你知道吗很难使用而且易碎。你知道吗
您可以实现
__iter__
方法。你知道吗通过这种方式,您可以执行以下操作:
以及
等等
您还可以实现:
__len__(self)
支持len(cct.filter_by().order_by())
。__getitem__(self,item)
支持cct.filter_by().order_by()[34]
。你知道吗相关问题 更多 >
编程相关推荐