我在Google上找不到关于此主题的任何内容,所以我想我应该在这里问一下:
是否可以使用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...
似乎存在一些用于创建此类功能的虚幻库,但我似乎无法理解为什么这样看起来如此复杂......
谢谢!
答案 0 :(得分:10)
只要函数返回一个值,就可以链接它。在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)
答案 1 :(得分:9)
以下是Simon 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
您可以更好地使用collections abstract base classes使ListMutator
完全像列表一样行动。实际上,您可以将list
本身子类化,尽管它可能会限制您执行某些您可能需要执行的操作...而且我不知道对子类化内置类型(如{{}的一般意见是什么1}}。
答案 2 :(得分:3)
如果我们谈论的是对象方法,那么它很简单,只需return self
来自每个方法。另一方面,如果你想链接未绑定的函数,那么按照你想要的方式链接它们对我来说真的没有意义。当然,它看起来不错,但它在语义上是不连贯的,因为“。”代表对象属性访问,而不是“链”。
答案 3 :(得分:1)
供将来参考:查看 Moka ,这是一个极简主义的函数式编程库。从他们的例子:
(List() # Create a new instance of moka.List
.extend(range(1,20)) # Insert the numbers from 1 to 20
.keep(lambda x: x > 5) # Keep only the numbers bigger than 5
.rem(operator.gt, 7) # Remove the numbers bigger than 7 using partial application
.rem(eq=6) # Remove the number 6 using the 'operator shortcut'
.map(str) # Call str on each numbers (Creating a list of string)
.invoke('zfill', 3) # Call zfill(x, 3) on each string (Filling some 0 on the left)
.insert(0, 'I am') # Insert the string 'I am' at the head of the list
.join(' ')) # Joining every string of the list and separate them with a space.
>>> 'I am 007'
答案 4 :(得分:0)
看看this。它是一个简单的链接包装类。它实现了一些underscore.js lib的功能。你用你的下划线包装你的列表,元组或字典,然后玩它然后通过附加另一个下划线来获取它的值。
print (_([1,2,3])
.map(lambda x: x+1)
.reverse()
.dict_keys(["a", "b", "c"])
.invert()
.items()
.append(("this is what you got", "chaining"))
.dict()._)
输出:
{2: 'c', 3: 'b', 4: 'a', 'this is what you got': 'chaining'}