2

functools モジュールの partial メソッドを使用して、関数を値の範囲にマップしています。

def basic_rule(p,b,vx=1,**kwargs):
    return (p / b) if vx != 0 else  0

def rule5(func,**kwargs):
    vals = map(functools.partial(func,**kwargs), range(1,kwargs['b']+1))
    return [x for i,x in enumerate(vals[:-1]) if x >= vals[i+1]] == []

rule5(basic_rule,p=100,b=10000)

5行目で発生するエラーは次のとおりです。

----> return map(functools.partial(func,**kwargs), range(1,kwargs['b']+1))

TypeError: basic_rule() got multiple values for keyword argument 'p'

functools.partial は、既に値を割り当てているにもかかわらず、範囲を引数 p に割り当てようとしているようです。範囲を vx の値に割り当てようとしています。どうすればそれを実現できるか考えていますか?

編集:コードに余分なコンテキストを少し追加しました。基本的にテスト 5 でやりたいことは、与えられた関数の結果が vt が上がるにつれて増加することを確認することです。 =n)。

4

1 に答える 1

3

functools.partialは、引数 receiveids を 2 つのプロパティに格納するパーシャルを生成します。

  • arguments位置引数を格納します
  • keywordsすべてのキーワードベースの引数を格納

したがって、パーシャルは元の関数を意図したとおりに呼び出すことができます。つまり、結果のパーシャルを 1 つの引数 (たとえば 1) で呼び出すと、次のようになります。

original_func(1, **kwargs)

最初の引数が含まれてkwargsいるため、「1」を位置引数として渡しているため、エラーが発生します。

この特定のケースでうまくいくかどうかはわかりませんが、 inspect.getargspeckwargsを使用して、位置引数として渡すことができる引数を抽出することが 1 つの解決策になる可能性があります。この場合、rule5関数は次のようになります。

def rule5(func, **kwargs):
    # let's save 'b' argument because we'll need it in the range call
    b = kwargs['b']
    original_args = inspect.getargspec(func).args
    # extract from kwargs all arguments that can be passed as positional
    new_args = [kwargs.pop(key) for key in original_args if key in kwargs]
    # construct the partial passing as much positional arguments as possible
    fn = functools.partial(func, *new_args, **kwargs)
    # now map will pass the range result as the next positional argument
    vals = map(fn, range(1, b+1))
    return [x for i,x in enumerate(vals[:-1]) if x >= vals[i+1]] == []
于 2016-07-03T23:06:19.127 に答える