如何通过引用调用多个python函数对一个变量进行操作,以便轻松更改函数调用的顺序?

How do I call multiple python functions by reference to operate on a variable so that I can change the sequence of function calls easily?

提问人:skeetastax 提问时间:10/31/2023 最后编辑:skeetastax 更新时间:10/31/2023 访问量:59

问:

我想创建一个“函数管道”,就像工厂一样。

假设我有以下功能:

def func1(var):
    var = # do something with var
    return var

def func2(var):
    var = # do something else with var
    return var

def func3(var):
    var = # do another thing with var
    return var

def func4(var):
    var = # do something with var we haven't done before
    return var

现在,我想按顺序调用对象上的所有函数,但我想测试以所有可能的顺序排列调用它们并检查结果,因为最终结果将根据调用函数的顺序而有所不同。

如何更改此手动函数调用序列:

myvar = something
myvar = func1(myvar)
myvar = func2(myvar)
myvar = func3(myvar)
myvar = func4(myvar) # final variable function transformation (result)

...变成我可以遍历所有可能的序列,但不必手动编码的东西,如下所示?

def func1(var):
    var = # do something with var
    return var

def func2(var):
    var = # do something else with var
    return var

def func3(var):
    var = # do another thing with var
    return var

def func4(var):
    var = # do something with var we haven't done before
    return var

myvar = func4(func3(func2(func1(myvar))))
# or
myvar = func3(func4(func2(func1(myvar))))
# or
myvar = func3(func2(func4(func1(myvar))))
# or
myvar = func3(func2(func1(func4(myvar))))
# or
myvar = func4(func2(func3(func1(myvar))))
# or
# ...etc...
# or (finally)
myvar = func1(func2(func3(func4(myvar))))
Python 函数 序列 按引用传递 调用

评论

0赞 skeetastax 10/31/2023
AFAICT,您链接到的那篇帖子中给出的每个示例都排列变量,而不是函数调用。我想调用所有序列排列中的函数。我想我需要获取所有函数的引用,然后将它们添加到列表中并置换它?
2赞 Barmar 10/31/2023
@skeetastax 置换变量和函数之间没有区别。只需在循环中调用排列的元素即可。
1赞 Barmar 10/31/2023
myvar = f1(f2(f3(f4(myvar))))
0赞 skeetastax 10/31/2023
是的。。。只是在 python 函数装饰器上看一些东西......现在开始看到这一点。
0赞 Mark Ransom 10/31/2023
函数是与其他任何对象一样的对象,您可以轻松地将它们分配给变量或列表。

答:

-1赞 nadapez 10/31/2023 #1

要获取所有函数排列,您可以使用itertools.permutations

此外,要将一系列函数应用于可以使用的值functools.reduce

import functools
import itertools

def applyfunc(val, func):
    return func(val)

def apply_sequence(sequence, val):
    return functools.reduce(applyfunc, sequence, val)

def apply_permutations(func_list, val):
    return map(apply_sequence,
               itertools.permutations(sequence))


# use it like this:

for v in apply_permutations([f1, f2, f3, f4], val):
    print v

评论

0赞 skeetastax 10/31/2023
import reduce失败。“pip install reduce”也失败。这个模块位于什么位置?
1赞 Joe 10/31/2023
Reduce在functools
0赞 Joe 10/31/2023
我看不出定义使用reduce的函数比@Barmar类似建议的更好ans = f1(f2(f3(f4(x))))
0赞 nadapez 10/31/2023
对不起,我应该导入 itertools 而不是 reduce。我吓坏了它
0赞 nadapez 10/31/2023
Reduce的使用使函数更加通用,可以应用于任意函数列表。
0赞 skeetastax 10/31/2023 #2

我解决了这个问题:

import itertools

def func1_square(var):
    var = var ** 2
    return var

def func2_triple(var):
    var = var * 3
    return var

def func3_quarter(var):
    var = var / 4
    return var

def func4_minus1(var):
    var = var - 1
    return var

funcseq = list(itertools.permutations([func1_square, func2_triple, func3_quarter, func4_minus1]))

#print("Number of unique function sequences: {}".format(len(funcseq)))

def callfuncseq(seq, this):
    f = 1
    for func in seq:
#        print("F: {}; function: {}".format(f, func))
        this = func(this)
        f = f + 1
    print("RESULT: {}".format(this))
    return this

def main(n):
    results = []
    s = 1
    for seq in funcseq:
        print("SEQ: {}".format(s))
        results.append(callfuncseq(seq, n))
        s = s + 1
    return results

input = 8
final = main(input)

评论

0赞 Joe 10/31/2023
根据您的代码,您可能希望使用 .enumerate