2012-01-16 20 views
4

こんにちは私は関数を受け取り、その引数関数を実行する関数を返す必要があります。 1000回、毎回それを議論する。私はこのようなものがあります:異なる引数で複数回Python関数を実行する

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

をしかし、それはこのようにその呼び出しを思わ:同じ引数で1000回F runner(f)(random.randint(1,UPPER_BOUND))実行されます。どのように正しく行うには?

答えて

7

runner()が返す関数inner()が呼び出された時点で、random.randint(1,UPPER_BOUND)が評価されているという問題が発生します。必要なのは、後で評価を延期することです。

あなたはこのような何かを試みることができる:callableは元の関数fが呼び出されるたびに呼び出され

>>> 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. 

注こと。また、callableは、タプルやリストのようなシーケンス型を返さなければならないことにも注意してください。

編集:あなたがfに他の引数を渡す必要がある場合は、このような何かでそれを行うことができます:あなたは、ループ内random.randit呼び出しを配置する必要があり

>>> 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 
1

あなたは、関数defintionにrandom.randintのあなたの計算を移動する必要があります:たとえば

、このようなものは、あなたが始める必要があり、@はあなたがあればhere上に読むことができますデコレータ構文ですあなたはそれに精通していません。

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は(定義時)に一度だけ実行されます理由を理解することはhereを参照してください臆面もなく他のポストからhello例を盗みます。

1

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)) 

これはあなたがやろうとしていたことです(醜いラムダは含まれません)。

関連する問題