Python:如何包装函数调用,而不是函数本身?

Python: How do I wrap function calls, not the functions themselves?

例如,我有函数 funcA()funcB()funcC()。我想调用这些函数中的每一个,但在每个函数之后,执行一系列其他函数,如 func1()func2()func3()func4().

我知道我可以:

funcA()
func1()
func2()
func3()
func4()
funcB()
....

或者我可以:

def funcCombined():
    func1()
    func2()
    func3()
    func4()

funcA()
funcCombined()
funcB()
funcCombined()
...

但是有没有更好的办法呢?我试着把它们放在一个列表中,比如:

funcs = [funcA(), funcB(), funcC()]

for func in funcs:
    x = func
    func1()
    func2()
    func3()
    func4()

但它似乎正在执行列表中的所有函数,然后然后在for循环中执行它们。

最好的方法是什么?

不要在你想要之前调用函数

funcs = [funcA, funcB, funcC]

for func in funcs:
    func()

您可以将函数存储在列表中而不是它们调用的返回值 - 函数是 Python 中的第一个 class 个对象 - 并在循环中调用它们,然后调用函数组每次调用:

funcs = (funcA, funcB, funcC)

for func in funcs:
    func()
    funcCombined()

当您认为每个函数在您第一次将它们放入列表时都被调用时,您是正确的。这是因为 funcA() 调用了 funcA。但是,您可以通过省略括号来引用 funcA --- 这是指函数本身。

您可以创建函数列表(无需调用它们)、遍历它们、调用它们,然后调用另一组函数,例如

funcs = [funcA, funcB, funcC]
for func in funcs:
    func()
    funcCombined()

如果您的函数采用不同的参数,请将它们存储在字典或第二个列表中

funcs = {
    funcA: (1, 2, 3), 
    funcB: ({'a' : 1}, [1, 2, 3]),
    funcC: None
}

for func, args in funcs.items(): 
     if args is None:
         func() 
     else:
         func(*args)

假设您存储函数对象列表而不是结果,它可以在一行中完成;

map(lambda func: func(), funcs)

注意:在 Python 3.x 中,映射 returns 生成器,但您可以通过转换为列表来绕过惰性求值;

list(map(lambda func: func(), funcs))

如果你想通过争论,请参阅itertools.starmap