Python 中的函数链

Python 中的函数链

在 Codewars.com 上,我遇到了以下任务:

创建一个函数 add 在连续调用时将数字加在一起。因此 add(1)1+2add(1)(2)1

虽然我熟悉 Python 的基础知识,但我从未遇到过可以这样连续调用的函数,即函数 f(x) 可以调用为 f(x)(y)(z)... .到目前为止,我什至不确定如何解释这个符号。

As a mathematician, I’d suspect that f(x)(y) is a function that assigns to every x a function g_{x} and then returns g_{x}(y) and同样适用于 f(x)(y)(z)

如果这种解释是正确的,Python 将允许我动态创建对我来说非常有趣的函数。在过去的一个小时里,我一直在网上搜索,但未能找到正确方向的线索。然而,由于我不知道这个编程概念是如何被调用的,所以这可能并不太令人惊讶。

你如何称呼这个概念,我在哪里可以阅读更多关于它的信息?

原文由 Stefan Mesken 发布,翻译遵循 CC BY-SA 4.0 许可协议


回答:

我不知道这是否是 函数 链接和 可调用 链接一样多,但是,由于函数 可调用的,我想这没有什么坏处。无论哪种方式,我可以想到两种方法:

子分类 int 和定义 __call__

第一种方法是使用自定义 int 定义 __call__ 的子类,它返回具有更新值的自身的新实例:

 class CustomInt(int):

def __call__(self, v):

return CustomInt(self + v)

函数 add 现在可以定义为返回一个 CustomInt 实例,作为返回自身更新值的可调用对象,可以连续调用:

 >>> def add(v):

... return CustomInt(v)

>>> add(1)

1

>>> add(1)(2)

3

>>> add(1)(2)(3)(44) # and so on..

50

In addition, as an int subclass, the returned value retains the __repr__ and __str__ behavior of int s. _但是,对于更复杂的操作,您应该适当地定义其他双下划线_。

正如@Caridorc 在评论中指出的那样, add 也可以简单地写成:

 add = CustomInt

将类重命名为 add 而不是 CustomInt 也同样有效。


定义一个闭包,需要额外调用以产生值:

我能想到的唯一其他方法涉及嵌套函数,该函数需要额外的空参数调用才能返回结果。我 没有 使用 nonlocal 并选择将属性附加到函数对象以使其在 Python 之间可移植:

 def add(v):

def _inner_adder(val=None):

"""

if val is None we return _inner_adder.v

else we increment and return ourselves

"""

if val is None:

return _inner_adder.v

_inner_adder.v += val

return _inner_adder

_inner_adder.v = v # save value

return _inner_adder

这会不断返回自身( _inner_adder ),如果提供 val ,则递增它( _inner_adder += val ),如果不是,则返回值。就像我提到的,它需要额外的 () 调用才能返回增加的值:

 >>> add(1)(2)()

3

>>> add(1)(2)(3)() # and so on..

6

原文由 Dimitris Fasarakis Hilliard 发布,翻译遵循 CC BY-SA 3.0 许可协议


回答:

你可以恨我,但这是一个单线:)

 add = lambda v: type("", (int,), {"__call__": lambda self, v: self.__class__(self + v)})(v)

编辑:好的,这是如何工作的?该代码与@Jim 的答案相同,但一切都发生在一行中。

  1. type 可用于构建新类型: type(name, bases, dict) -> a new type 。对于 name 我们提供空字符串,因为在这种情况下并不真正需要名称。对于 bases (元组),我们提供了一个 (int,) ,它等同于继承 intdict 是类属性,我们在其中附加 __call__ lambda。
  2. self.__class__(self + v) 等同于 return CustomInt(self + v)
  3. 新类型在外层 lambda 中构造并返回。

原文由 Jordan Jambazov 发布,翻译遵循 CC BY-SA 3.0 许可协议

以上是 Python 中的函数链 的全部内容, 来源链接: utcz.com/p/938666.html

回到顶部