Python中的函数链接

发布于 2021-01-29 19:26:46

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

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

关注者
0
被浏览
45
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

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

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


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看