Python 中的函数链
在 Codewars.com 上,我遇到了以下任务:
创建一个函数
add
在连续调用时将数字加在一起。因此add(1)
1+2
add(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 的答案相同,但一切都发生在一行中。
type
可用于构建新类型:type(name, bases, dict) -> a new type
。对于name
我们提供空字符串,因为在这种情况下并不真正需要名称。对于bases
(元组),我们提供了一个(int,)
,它等同于继承int
。dict
是类属性,我们在其中附加__call__
lambda。self.__class__(self + v)
等同于return CustomInt(self + v)
- 新类型在外层 lambda 中构造并返回。
原文由 Jordan Jambazov 发布,翻译遵循 CC BY-SA 3.0 许可协议
以上是 Python 中的函数链 的全部内容, 来源链接: utcz.com/p/938666.html