如何将参数传递给函数指针参数?

58
我刚开始学习 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次。有没有一种方法可以实现这个目标而不必将"test"传递给repeat而是传递foo

9
注:这不是“函数指针”!在Python中,函数是对象。 - Michael Mauderer
注意:在某些情况下需要确切的函数签名,请参考python - Wrap callback function to include extra argument when caller verifies exact callback signature - Stack Overflow - user202729
3个回答

83

你可以使用一个 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添加关键字参数。)

20
您需要将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)

2
虽然这里的许多答案都很好,但这个答案可能会有所帮助,因为它不会引入任何不必要的重复,而回调函数之所以存在通常是为了与主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)

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