Python中是否有链调用方法?

时间:2016-01-05 14:04:12

标签: python

Python中是否有一个函数可以执行此操作:

val = f3(f2(f1(arg)))

键入此(例如):

val = chainCalling(arg,f3,f2,f1)

我想,因为python(可以说)是一种函数式语言,我正在寻找的函数会使语法更明亮

4 个答案:

答案 0 :(得分:9)

使用reduce() function链接来电:

from functools import reduce

val = reduce(lambda r, f: f(r), (f1, f2, f3), arg)

我使用了forward-compatible functools.reduce() function;在Python 3中,reduce()不再位于内置命名空间中。

答案 1 :(得分:2)

您可以使用reduce() functool - 正如Martijn所提出的那样,或者您可以非常简单地自己编写:

def chainCalling(arg, *funcs):
    if len(funcs) > 0:
        return chainCalling(funcs[0](arg), funcs[1:])
    return arg

或者,作为替代方法,不使用递归 - 因此不受限于调用堆栈限制,如Martijn所建议的那样:

def chainCalling(arg, *funcs):
    result = arg
    for f in funcs:
        result = f(result)
    return result

显然,你会想要这样称呼它,以避免无用的反转:

chainCalling(arg, f1, f2, f3)

答案 2 :(得分:0)

可能有点晚了,但是请在下面尝试我的解决方案。 chain_func本质上创建了一个新的包装函数,该函数在运行时调用时会调用链中的所有基础函数。

def chain_func(*funcs):
    def _chain(*args, **kwargs):
        cur_args, cur_kwargs = args, kwargs
        ret = None
        for f in reversed(funcs):
            cur_args, cur_kwargs = (f(*cur_args, **cur_kwargs), ), {}
            ret = cur_args[0]
        return ret

    return _chain

答案 3 :(得分:0)

如果您想将函数链应用于多个参数,您可以创建一个聚合函数。

g = lambda x: f3(f2(f1(x)))

或更灵活(当有任意函数列表时):

from functools import reduce, partial

f3 = lambda x: -x
f2 = lambda x: x ** 2
f1 = lambda x: x + 1
function_list = (f1, f2, f3)
g = partial(reduce, lambda r, f: f(r), function_list)
print(g(3))  # results in -16