小编典典

Python中的函数链接

python

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

创建一个函数add,该函数在连续调用时将数字加在一起。所以add(1)应该返回1add(1)(2)应该返回1+2,…

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

作为一个数学家,我怀疑f(x)(y)是分配到每个功能x的函数g_{x},然后返回g_{x}(y),同样也f(x)(y)(z)

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

您如何称呼这个概念?在哪里可以阅读更多有关它的信息?


阅读 187

收藏
2020-12-20

共1个答案

小编典典

我不知道 函数 链接和 可调用 链接是否一样多,但是,由于函数 可调用的,所以我猜没有什么坏处。无论哪种方式,我都可以通过两种方式来考虑:

子类化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

另外,作为int子类,返回值保留的__repr____str__行为int但是,对于更复杂的操作,应适当定义其他标记

正如@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提供了a,则将其递增(_inner_adder += val),否则,将按原样返回值。就像我提到的,它需要额外的()调用才能返回增加的值:

>>> add(1)(2)()
3
>>> add(1)(2)(3)()  # and so on..
6
2020-12-20