在codewars.com上,我遇到了以下任务:
Create a function
add
that adds numbers together when called in succession. Soadd(1)
should return1
,add(1)(2)
should return1+2
, ...
虽然我熟悉Python的基本知识,但我从未遇到过可以连续调用的函数,即可以调用为f(x)(y)(z)...
的函数f(x)
。到目前为止,我甚至不知道如何解释这个符号。
作为一名数学家,我怀疑f(x)(y)
是一个函数,它为每个x
分配一个函数g_{x}
,然后返回g_{x}(y)
,同样地,对于f(x)(y)(z)
。
如果这个解释是正确的,Python将允许我动态地创建对我来说非常有趣的函数。我在网上搜索了一个小时,但找不到正确方向的线索。然而,由于我不知道这个编程概念是如何被调用的,这可能并不太令人惊讶。
你怎么称呼这个概念?我在哪里能读到更多关于它的资料?
如果要定义要多次调用的函数,首先需要每次返回一个可调用对象(例如函数),否则必须通过定义
__call__
属性来创建自己的对象,以使其可调用。下一点是需要保留所有参数,在本例中,这意味着您可能需要使用Coroutines或递归函数。但请注意,协同路由比递归函数优化/灵活得多,特别是对于此类任务。
下面是一个使用协程的示例函数,它保留了自身的最新状态。注意,不能多次调用它,因为返回值是一个不可调用的
integer
,但是您可以考虑将其转换为预期的对象;-)。你可以恨我,但这里有一句话:)
编辑:好的,这是怎么回事?代码与@Jim的答案相同,但所有事情都发生在一行上。
type
可用于构造新类型:type(name, bases, dict) -> a new type
。对于name
我们提供空字符串,因为在这种情况下并不真正需要名称。对于bases
(元组),我们提供一个(int,)
,它与继承int
相同。dict
是类属性,我们在其中附加__call__
lambda。self.__class__(self + v)
与return CustomInt(self + v)
相同我不知道这是否是函数链接,正如它是可调用的链接一样,但是,由于函数是可调用的,我想没有造成任何伤害。不管怎样,我有两种方法可以考虑这样做:
分类
int
并定义__call__
:第一种方法是使用自定义的} ,该子类使用更新的值返回自身的新实例:
int
子类定义^{函数
add
现在可以定义为返回一个CustomInt
实例,该实例作为返回自身更新值的可调用实例,可以连续调用:此外,作为一个
int
子类,返回值保留__repr__
和__str__
s的int
行为。不过,对于更复杂的操作,应该适当定义其他dunders。正如@Caridorc在评论中指出的,
add
也可以简单地写成:将类重命名为
add
,而不是CustomInt
也同样适用。定义一个闭包,需要额外的调用来产生值:
我唯一能想到的另一种方法是使用嵌套函数,该函数需要额外的空参数调用才能返回结果。我不会使用
nonlocal
并选择将属性附加到函数对象,使其在Pythons之间可移植:这会连续返回自身(
_inner_adder
),如果提供了val
,则会递增(_inner_adder += val
),如果没有,则返回原样的值。就像我提到的,它需要额外的()
调用才能返回递增的值:相关问题 更多 >
编程相关推荐