用不同参数多次运行Python函数

4 投票
3 回答
5841 浏览
提问于 2025-04-17 10:19

你好,我需要一个函数,这个函数可以接收另一个函数作为参数,然后返回一个新的函数,这个新函数会执行传入的那个函数,比如说执行1000次,并且每次都用不同的参数来调用它。我有类似这样的代码:

def runner(f):
    def inner(*args):
        for i in xrange(1000):
            f(*args)
    return inner

但是当我这样调用的时候:runner(f)(random.randint(1,UPPER_BOUND)),发现这个函数f每次都是用同一个参数执行1000次。请问我该怎么做才能正确实现呢?

3 个回答

1

你需要把 random.randit 这个调用放在循环里面:

def runner(function):
    def inner(callable, args=()):
        for i in xrange(1000):
            function(callable(*args))
    return inner

然后你可以调用这个运行器:

runner(f)(random.randint, args=(1, UPPER_BOND))

我觉得这就是你想要做的事情,(而且不需要用到复杂的 lambda 表达式)。

1

你需要把随机数计算的部分放到函数定义里面:

比如,像下面这样就可以开始了,@ 是装饰器的语法,如果你不太了解,可以在这里看看。这里我借用了另一个帖子里的 hello 示例:

import random

UPPER_BOUND = 1000

def runner(fn):
    def wrapped():
        for i in range(0,10):
            stuff = random.randint(1,UPPER_BOUND)
            print(str(stuff) + ': ' + fn())
    return wrapped

@runner
def hello():
    return 'hello world'


if __name__=='__main__':
    hello()

补充:你还可以查看这里,了解为什么你的 random.randint 只执行了一次(在定义的时候),这就是为什么你的函数每次都得到相同的参数。

7

你遇到的问题是,random.randint(1,UPPER_BOUND) 这个代码在调用 runner() 返回的 inner() 函数时只会被计算一次。你需要的是把这个计算延迟到稍后再进行。

你可以试试下面这种写法:

>>> def runner(f, callable):
...   def inner():
...     for i in xrange(1000):
...       f(*callable())
...   return inner
... 
>>> runner(f, lambda: (random.randint(1, 1000),))()
603
385
321
etc.

注意,每次调用原始函数 f 时,callable 也会被调用。同时,callable 必须返回一个序列类型,比如元组或列表。

补充:如果你需要给 f 传递其他参数,可以用下面这种方式:

>>> def runner(f, callable):
...   def inner(*args, **kwds):
...     for i in xrange(1000):
...       pos = list(callable())
...       pos.extend(args)
...       f(*pos, **kwds)
...   return inner
... 
>>> def f(a, b, c, d = 3):
...   print a, b, c, d
... 
>>> runner(f, lambda: (random.randint(1,1000),))(3, 5, d = 7)
771 3 5 7
907 3 5 7
265 3 5 7

撰写回答