如何组合(组合)几个带参数的函数调用

How to compose (combine) several function calls with arguments

我的完整问题听起来是这样的:如何在不使用部分函数的情况下组合(组合)几个带参数的函数调用。

现在下面的当前代码工作正常,但每次提供任何附加参数时我都需要调用 partial:

    from functools import partial

    def pipe(data, *funcs):
        for func in funcs:
            data = func(data)
        return data

    def mult(data, amount=5, bias=2):
        return data*amount + bias

    def divide(data, amount, bias=1):
        return data/amount + bias

    result = pipe(5,
                    mult, 
                    partial(divide, amount=10)
                 )
    print(result)
    # 3.7

但我想部分地在管道函数内部调用。所以调用应该开始这样看:

    result = pipe(5,
                     mult, 
                     divide(amount=10)
                 )

下面是一个可能对您有所帮助的实现。它是一个用于函数的装饰器,因此您可以通过调用函数本身来创建 partial 函数,而不是 partial(func, ...):

from functools import partial, wraps

def make_partial(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        return partial(func, *args, **kwargs)
    return wrapper

对于任何你想要你的行为的函数,像这样装饰它:

@make_partial
def divide(data, amount, bias=1):
    return data/amount + bias

现在您可以调用 pipe,就像您现在描述的调用 divide(amount=10) 一样 returns 也是部分调用。

result = pipe(5, mult, divide(amount=10))

很难在 pipe 中进行 partial 调用,因为您可能需要以某种方式传入所需的函数及其默认参数而不调用它。此方法试图消除这种情况并保持现有功能的清洁。


我可以建议的唯一其他方法是传递一个函数列表、一个部分参数列表列表和一个关键字参数字典列表。您的函数签名将为 pipe(data, funcs, args, kwargs)

def pipe(data, funcs, args, kwargs):
    for func, arg_list, kwarg_list in zip(funcs, args, kwargs):
        data = partial(func, *arg_list, **kwarg_list)(data)
    return data

调用pipe,有点复杂:

result = pipe(
    5,
    [mult, divide],
    [[], []],
    [{}, {'amount': 10}]
)