Python用任意数量的变量进行curry

Kev*_*vin 6 python currying python-2.7

我正在尝试使用currying在Python中进行简单的功能添加.我在这里找到了这个咖喱装饰.

def curry(func):     
    def curried(*args, **kwargs):
        if len(args) + len(kwargs) >= func.__code__.co_argcount:
            return func(*args, **kwargs)
        return (lambda *args2, **kwargs2:
            curried(*(args + args2), **dict(kwargs, **kwargs2)))
    return curried

@curry
def foo(a, b, c):
    return a + b + c
Run Code Online (Sandbox Code Playgroud)

现在这很棒,因为我可以做一些简单的讨论:

>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6
Run Code Online (Sandbox Code Playgroud)

但这仅适用于三个变量.如何编写函数foo以便它可以接受任意数量的变量并且仍然可以调整结果?我尝试过使用*args的简单解决方案,但它没有用.

编辑:我已经查看了答案,但仍然无法弄清楚如何编写一个可以执行如下所示的函数:

>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6
>>> foo(1)(2)
3
>>> foo(1)(2)(3)(4)
10
Run Code Online (Sandbox Code Playgroud)

Kar*_*tel 6

可以说explicit is better than implicit:

from functools import partial

def example(*args):
    print("This is an example function that was passed:", args)

one_bound = partial(example, 1)
two_bound = partial(one_bound, 2)
two_bound(3)
Run Code Online (Sandbox Code Playgroud)

@JohnKugelman用你要做的事情解释了设计问题 - 对"curried函数"的调用在"添加更多curried参数"和"调用逻辑"之间是模糊的.这个问题在Haskell(概念来自于)中不是问题的原因是语言懒惰地评估所有内容,所以在"一个名为不接受参数且只返回3 的函数"之间没有区别x和"对上述功能的调用",或者甚至在那些和"整数3"之间.Python不是那样的.(例如,您可以使用零参数调用来表示"立即调用逻辑";但这会破坏special cases aren't special enough,并且在您实际上不想进行任何干扰的简单情况下需要额外的一对括号.)

functools.partial是一个在Python中部分应用函数的开箱即用解决方案.不幸的是,反复调用partial添加更多"curried"参数并不是那么有效(partial在引擎盖下会有嵌套对象).但是,它更灵活; 特别是,您可以将它用于没有任何特殊装饰的现有功能.