55

我刚开始学习Python,发现我可以将一个函数作为另一个函数的参数传递。现在,如果我调用foo(bar())它,它不会作为函数指针传递,而是作为使用函数的返回值传递。调用foo(bar)将传递函数,但这样我无法传递任何额外的参数。如果我想传递一个调用的函数指针bar(42)怎么办?

无论我传递给它什么参数,我都希望能够重复一个函数。

def repeat(function, times):
    for calls in range(times):
        function()

def foo(s):
        print s

repeat(foo("test"), 4)

在这种情况下,该函数foo("test")应该被连续调用 4 次。有没有办法做到这一点而不必通过“测试”来repeat代替foo

4

3 回答 3

79

您可以使用lambda

repeat(lambda: bar(42))

或者functools.partial

from functools import partial
repeat(partial(bar, 42))

或者分别传递参数:

def repeat(times, f, *args):
    for _ in range(times):
        f(*args)

这种最终风格在标准库和主要 Python 工具中很常见。*args表示可变数量的参数,因此您可以将此函数用作

repeat(4, foo, "test")

或者

def inquisition(weapon1, weapon2, weapon3):
    print("Our weapons are {}, {} and {}".format(weapon1, weapon2, weapon3))

repeat(10, inquisition, "surprise", "fear", "ruthless efficiency")

请注意,为方便起见,我将重复次数放在前面。*args如果要使用构造,它不能是最后一个参数。

(为了完整起见,您也可以使用 . 添加关键字参数**kwargs。)

于 2012-12-08T23:56:54.533 回答
19

您需要将 foo 的参数传递给 repeat 函数:

#! /usr/bin/python3.2

def repeat (function, params, times):
    for calls in range (times):
        function (*params)

def foo (a, b):
    print ('{} are {}'.format (a, b) )

repeat (foo, ['roses', 'red'], 4)
repeat (foo, ['violets', 'blue'], 4)
于 2012-12-09T00:00:32.800 回答
1

虽然这里的许多答案都很好,但这个答案可能会有所帮助,因为它不会引入任何不必要的重复,而且首先回调的原因通常是与主 UI 线程之外的其他工作同步。

享受!

import time, threading

def callMethodWithParamsAfterDelay(method=None, params=[], seconds=0.0):

    return threading.Timer(seconds, method, params).start()

def cancelDelayedCall(timer):

    timer.cancel()

# Example
def foo (a, b):

    print ('{} are {}'.format (a, b) )

callMethodWithParametersAfterDelay(foo, ['roses', 'red'], 0)
于 2018-01-08T13:13:48.267 回答