Python: 类jQuery的函数链式调用?
我在谷歌上找不到关于这个主题的任何信息,所以我想在这里问一下:
在Python中,能像jQuery那样把多个函数连在一起使用吗?
['my', 'list'].foo1(arg1, arg2).foo2(arg1, arg2).foo3(arg1, arg2) #etc...
我写的代码占用了很多空间,而且可读性也不高:
foo3(foo2(foo1(['my', 'list'], arg1, arg2), arg1, arg2), arg1, arg2) #etc...
似乎有一些神秘的库可以用来创建这样的函数,但我不明白为什么这看起来要这么复杂...
谢谢!
5 个回答
3
如果我们在讨论对象的方法,那就很简单了,只需要在每个方法里写上 return self
就可以了。另一方面,如果你想把不属于任何对象的函数连在一起,我觉得这样连起来没有什么意义。虽然看起来不错,但从语义上来说,这样用不太合适,因为“.”这个符号是用来访问对象的属性,而不是用来表示“连锁”的。
11
只要函数能返回一个值,你就可以进行链式调用。在jQuery中,选择器方法通常会返回选择器本身,这就是你可以进行链式调用的原因。如果你想在Python中实现链式调用,可以这样做:
class RoboPuppy:
def bark(self):
print "Yip!"
return self
def growl(self):
print "Grr!"
return self
pup = RoboPuppy()
pup.bark().growl().bark() # Yip! Grr! Yip!
不过,你的问题似乎是你的函数参数太紧凑了。链式调用并不是解决这个问题的方法。如果你想简化函数参数,可以在把参数传给函数之前,先把它们赋值给变量,像这样:
spam = foo(arg1, arg2)
eggs = bar(spam, arg1, arg2)
ham = foobar(eggs, args)
10
这是对西蒙的 ListMutator
建议的进一步扩展:
class ListMutator(object):
def __init__(self, seq):
self.data = seq
def foo1(self, arg1, arg2):
self.data = [x + arg1 for x in self.data]
# This allows chaining:
return self
def foo2(self, arg1, arg2):
self.data = [x*arg1 for x in self.data]
return self
if __name__ == "__main__":
lm = ListMutator([1,2,3,4])
lm.foo1(2, 0).foo2(10, 0)
print lm.data
# Or, if you really must:
print ListMutator([1,2,3,4]).foo1(2, 0).foo2(10, 0).data
你可以更进一步,让 ListMutator
完全像一个列表一样工作,方法是使用 集合抽象基类。实际上,你可以直接继承 list
,不过这样可能会限制你做某些你需要的事情……而且我不知道大家对继承像 list
这样的内置类型的看法是什么。