Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:dosomethinghere().dependent().on().thismethod()?_Python_Python 3.x_Python 2.x - Fatal编程技术网

Python:dosomethinghere().dependent().on().thismethod()?

Python:dosomethinghere().dependent().on().thismethod()?,python,python-3.x,python-2.x,Python,Python 3.x,Python 2.x,如果我编写这样的代码,我可以将对象实例上的方法调用链接在一起: 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 se

如果我编写这样的代码,我可以将对象实例上的方法调用链接在一起:

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\u list()
调用根据
order\u by
设置的值执行某些操作。当然,在执行
order\u by
时,
get\u list
已经完成了执行,所以我不能这样做。或者我可以吗

我考虑过使用
get_list
filter_by
order_by
和其他类似的方法来更新函数调用堆栈,然后在最后执行它们。。。当然,除了没有办法知道你已经走到了尽头

这将允许这种情况发生

cct.get_list().filter_by().order_by()
cct.now_actually_do_it()
其中
now\u实际上\u do\u it
消耗了前一行代码创建的函数堆栈,但我真的希望能够在一行中完成这项工作



编辑1:为了清楚起见,我只提到了
现在实际上做了它,作为如何做的指示,但我真的不想这样做。

在这种情况下,您希望有一个链接类型的调用,但是您不能返回
self
,因为
order\u by()
不作用于
filter\u by()
创建的过滤结果集,但作用于原始
cct
对象

相反,每个方法都应该返回一个结果集,该结果集还具有用于添加过滤等的方法

另一方面,Python已经为其中的大部分内置了:

filter(filter_fun, sorted(cct.get_list(), key=keyfun))
因此,这样做的唯一原因是,如果您实际构建的查询被延迟到对库的调用或服务调用,就像ORM一样。在这种情况下,您应该构建一个包含过滤和排序命令的对象链并返回它,然后在调用时解析和执行该链

在上述函数中返回
self
,在任何情况下都没有什么用处

当然,除非您在每次调用中都实际修改了self,但如果您这样做,您的链接调用API将很混乱。修改自我意志也是如此 表示对象保留的状态不是对象的一部分,而是调用的一部分。例如,您可以让
.filter\u by()
在对象上设置一个过滤器,该过滤器由
.get\u list()
使用。但是,在创建新的
.get_list()
之前,必须重置该筛选器,否则该筛选器仍将处于活动状态


这很难使用,也很脆弱。

您可以实现
方法

class ChainClassTest(object):

    ...

    def __iter__(self):
        for i in self.now_actually_do_it():
            yield i
这样,您就可以执行以下操作:

>>> my_list = list(cct.filter_by().order_by())

等等

您还可以实现:
\uuuu len(self)
支持
len(cct.filter\u by().order\u by())


\uu getitem(self,item)
支持
cct.filter\u by().order\u by()[34]

如果您想实现,您不会
返回self
,而是返回某种类型的StatementBuilder实例,该实例收集所有参数,直到您
现在才真正执行它。
。您不只是以不同的顺序调用它吗
cct.filter\u by().order\u by().get\u list()
。让
get_list
返回一个列表而不是self。将其作为任何链接的结尾。如果将actuallydoit方法附加到链的结尾,会不会有什么不好的结果?这是一种非常流行的模式。否则,您将不得不对代码进行初步检查,这将超出纯python的范围。不确定您要问什么,因为您还没有回答自己。不能让较早的方法调用依赖于较晚的方法调用。您可以将所有调用堆积到一个堆栈中,然后执行一个“finish”操作来解析所有调用,但如果没有一个明确的“finish”,您就无法做到这一点,原因正是您提到的:方法无法知道它是否是链中的最后一个。(不过,“finish”不需要单独的一行;您可以执行
obj.a().b().c().finish()
)这是一种典型的ORM实现模式,用于链接和“建立状态”。也称为延迟加载/评估,它仍然在
之前执行
。get\u list()
。filter\u by()
。由于计算是惰性的,您可以让
.filter\u by()
self
上设置一个过滤器,该过滤器由
使用。get\u list()
,但在再次调用
.get\u list()
之前,您必须重置该过滤器。对象将保留一个状态,该状态只应是方法调用的一部分。这是糟糕的设计,会导致麻烦。
get\u list
是我的错误,我的意思是你不需要它,你可以把iys逻辑放在
\u iter\u
中。我修复了我的答案。无论调用什么函数,我的注释仍然有效。;-)因此,我不确定我是否理解您的意思,OP希望
filter\u by()
更改对象行为
>>> for item in cct.filter_by().order_by():
...    print item