Python函数链式调用未知次数

3

有没有一种方法可以在一个对象上使用同一个函数不知道多少次?

例如,如果我想在对象obj上链接函数fn两次,我会写成:

fn(fn(obj))

最初的回答:

obj.fn(**kwargs1).fn(**kwargs2)

如果我想要将一个fn函数链接五次,我会这样做:

最初的回答:

obj.fn(**kwargs1).fn(**kwargs2).fn(**kwargs3).fn(**kwargs4).fn(**kwargs5)

虽然对于问题的答案来说并不重要,但使用情况是我正在使用一个API,每一行代码都会向服务器发出请求。我想要尽量减少请求的次数,所以想要链式调用函数。但是,我在开始时并不知道我希望链式调用函数的次数。 - Ian
fn是什么样子的? - Devesh Kumar Singh
你可以使用递归函数和计数器,可以手动设置计数器或者使用退出条件。 - G. Anderson
为了对问题陈述增加更多细节:我正在使用Python的Gremlin包装器。该对象是一个顶点,fn函数的定义是property(name, value),它将一个新属性分配给图中的顶点。当代码行执行时,它会将查询发送到Gremlin服务器,并使用新的属性值更新指定的顶点。(但所有这些都被抽象化了) - Ian
没错。我将遍历一个列表,该列表指定了每个项目的迭代次数,以及传递给每个fn调用的参数。 - Ian
显示剩余4条评论
1个回答

4
您可以使用一个简单的 for 循环,它遍历参数列表,并将每个参数应用于对象,并将结果重新分配回对象。
for args in list_of_args:

    obj = obj.fn(*args)

例如,我可以使用这个逻辑来链接 string.replace,如下所示。
obj = 'aaaccc'
list_of_args = [['a','b'], ['c','d']]

for args in list_of_args:
    obj = obj.replace(*args)

print(obj)

输出结果将为:

bbbddd

这与执行'aaabbb'.replace('a','b').replace('c','d')相同。

或者我们也可以使用递归方法,它接受对象,一个计数器作为当前要应用的参数的索引,以及函数需要运行的次数。

#fn is either defined, or imported from outside
def chain_func(obj, counter, max_count):

    #If counter reaches max no of iterations, return
    if counter == max_count:
        return obj

    #Else recursively apply the function
    else:
        return chain_func(obj.fn(list_of_args[counter]), counter+1, max_count)

#To call it twice
list_of_args = [kwargs1, kwargs2]
chain_func(obj, 0, 2)

例如,我可以使用这个逻辑来链式调用 string.replace 如下。
def chain_func(obj, counter, max_count):

    #If counter reaches max no of iterations, return
    if counter == max_count:
        return obj

    #Else recursively apply the function
    else:
        return chain_func(obj.replace(*list_of_args[counter]), counter+1, max_count)


list_of_args = [['a','b'], ['c','d']]
print(chain_func('aaaccc', 0, 2))

输出将会是:

bbbddd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接