Python处理任意数量的变量

2024-05-16 04:19:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用curry来制作一个简单的函数性的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

这很好,因为我可以做一些简单的咖喱菜:

^{pr2}$

但这只适用于三个变量。如何编写foo函数,以便它可以接受任意数量的变量,并且仍然能够返回结果?我没试过用简单的方法。在

编辑:我已经看了答案,但还是不知道如何编写一个可以执行的函数,如下所示:

>>> foo(1)(2, 3)
6
>>> foo(1)(2)(3)
6
>>> foo(1)(2)
3
>>> foo(1)(2)(3)(4)
10

Tags: 函数插件lenreturnfoodefargs装饰
3条回答

事实1:对于一个可变函数,实现一个自动货币化函数是完全不可能的。在

事实2:如果你想让传递给它的函数知道它将被curry处理,从而使它的行为有所不同,那么你可能没有在搜索curry。在

如果您需要的是一种处理可变函数的方法,那么您应该按照以下几行进行操作(使用您自己的剪贴):

def curryN(arity, func):
    """curries a function with a pre-determined number of arguments"""
    def curried(*args, **kwargs):
        if len(args) + len(kwargs) >= arity:
            return func(*args, **kwargs)
        return (lambda *args2, **kwargs2:
            curried(*(args + args2), **dict(kwargs, **kwargs2)))
    return curried

def curry(func):
    """automatically curries a function"""
    return curryN(func.__code__.co_argcount, func);

您可以这样做:

^{pr2}$

您可以为自己实现与functools.partial示例相同的事情,如下所示:

def curry (prior, *additional):
    def curried(*args):
        return prior(*(args + additional))
    return curried

def add(*args):
    return sum(args)

x = curry(add, 3,4,5)
y = curry(b, 100)
print y(200)
# 312

curry视为函数工厂而不是装饰器可能更容易;从技术上讲,这是装饰器所做的全部工作,但装饰器使用模式是静态的,其中工厂是您希望作为操作链的一部分调用的东西。在

您可以在这里看到,我以add作为curry的参数,而不是add(1)或其他东西:工厂签名是<callable>, *<args>。这就解决了原帖子评论中的问题。在

可以说,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)

@JohnKugelman解释了你试图做的设计问题——对curried函数的调用在“添加更多curried参数”和“调用逻辑”之间是不明确的。在Haskell中这不是一个问题的原因(这个概念来自于Haskell),因为语言对所有东西的求值都是懒惰的,所以对于“一个名为x的函数,它不接受任何参数,只返回3”和“对前面提到的函数的调用”之间,或者两者之间没有区别和“整数3”。Python不是这样的。(例如,您可以使用零参数调用来表示“立即调用逻辑”;但这将中断special cases aren't special enough,对于不想执行任何curry操作的简单情况,需要额外的一对括号。)

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

相关问题 更多 >