Python:类似 jQuery 的函数链?

发布于 2024-10-05 18:47:53 字数 419 浏览 4 评论 0 原文

我在 Google 上找不到任何关于这个主题的内容,所以我想我应该在这里问:

Is it possible to chainfunctions with Python, like jQuery does?

['my', 'list'].foo1(arg1, arg2).foo2(arg1, arg2).foo3(arg1, arg2) #etc...

当我编写这段代码时,我失去了很多空间和可读性:

foo3(foo2(foo1(['my', 'list'], arg1, arg2), arg1, arg2), arg1, arg2) #etc...

似乎存在一些用于创建此类函数的虚幻库,但我似乎不明白为什么这必须看起来如此复杂......

谢谢!

I couldn't find anything on this subject on Google, so I think I should ask it here:

Is it possible to chain functions with Python, like jQuery does?

['my', 'list'].foo1(arg1, arg2).foo2(arg1, arg2).foo3(arg1, arg2) #etc...

I am losing a lot of space and readability when I write this code:

foo3(foo2(foo1(['my', 'list'], arg1, arg2), arg1, arg2), arg1, arg2) #etc...

There seems to exist some illusive library for creating such functions, but I can't seem to see why this has to be so complicated-looking...

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

枫以 2024-10-12 18:47:53

只要函数返回一个值,就可以将其链接起来。在 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)

As long as the function returns a value, you can chain it. In jQuery, a selector method usually returns the selector itself, which is what allows you to do the chaining. If you want to implement chaining in python, you could do something like this:

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!

Your problem, however, seems to be that your function arguments are too cramped. Chaining is not a solution to this. If you want to condense your function arguments, just assign the arguments to variables before passing them to the function, like this:

spam = foo(arg1, arg2)
eggs = bar(spam, arg1, arg2)
ham = foobar(eggs, args)
心作怪 2024-10-12 18:47:53

这是 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

您可以做得更好,通过使用 ListMutator 完全像一个列表一样工作.org/library/collections.html#abcs-abstract-base-classes" rel="noreferrer">集合抽象基类。事实上,您可以对 list 本身进行子类化,尽管它可能会限制您做某些您可能需要做的事情......而且我不知道对子类化内置类型的普遍看法是什么就像列表

Here's an expansion of Simon's ListMutator suggestion:

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

You could go one better and make ListMutator act entirely like a list by using the collections abstract base classes. In fact, you could subclass list itself, although it may restrict you from doing certain things you might need to do... and I don't know what the general opinion is on subclassing built-in types like list.

往事风中埋 2024-10-12 18:47:53

如果我们谈论对象方法,那么这很简单,只需从每个方法中返回 self 即可。另一方面,如果您想链接未绑定的函数,那么按照您想要的方式链接它们对我来说并没有什么意义。当然,它看起来不错,但它在语义上不连贯,因为“。”代表对象属性访问而不是“链”。

If we're talking about object methods, then it's trivial, just return self from every method. On the other hand, if you would like to chain unbound functions, it doesn't really make sense to me to chain them the way you want to. Sure, it looks nice, however it's semantically incoherent because the "." stands for object attribute access and not for "chain".

一生独一 2024-10-12 18:47:53

供将来参考:看看 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'

For future reference: have a look at Moka, a minimalist functional programming library. From their examples:

(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'
刘备忘录 2024-10-12 18:47:53

看看这个。它是一个简单的链接包装类。它实现了 underscore.js 库的一些功能。您可以用下划线包装列表、元组或字典,然后使用它,然后通过附加另一个下划线从中获取值。

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'}

Take a look at this. It is A simple wrapper class for chaining. And it implemented some of the underscore.js lib's functionality. You wrap your list, tuple or dict with an underscore, and play with it then get the value out of it by appending another underscore.

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()._)

output:

{2: 'c', 3: 'b', 4: 'a', 'this is what you got': 'chaining'}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文