2017-10-11 10 views
0

私はいくつかの関数が多くの入力変数を必要とするコードを書いています。だから、これらの入力変数を辞書を介して呼び出し可能なkwargsにすることは良い考えだと思った。親関数によって呼び出される関数kwargsに問題があります。簡単な例として、以下のコードを考えてみましょう。辞書項目を親関数と子関数の関数kwargとしてどのように使うことができますか?

import numpy as np 

## generate some data and call function via dict 

def f(x): 
    return np.cos(x) 

data_one = np.linspace(1, 10, 10) # x 
data_two = f(data_one) # y 

xy_dict = dict(x=data_one, y=data_two) ## put x,y into dict 

def try_dict_ops(x, y): 
    c = [x[i] - y[i] for i in range(len(x)) if len(x) == len(y)] 
    return np.array(c) 

print(try_dict_ops(**xy_dict)) 
## prints array, it works 

ここでは、親機能とそれに対応するデータを紹介します。

abxy_dict = dict(a=1, b=4, x=data_one, y=data_two) 

def try_nested_dict_ops(a, b, x, y): 
    g = [try_dict_ops(x, y)[i] * a + b for i in range(len(x))] 
    return np.array(g) 

print(try_nested_dict_ops(**abxy_dict)) 
## prints array, it works 

私の質問は、上で定義したサブ関数を呼び出す親関数を呼び出すさまざまな方法に関するものです。 xyabxy_dictに明示的に入れないと、これを行う簡単な方法はありますか?さらに、親関数が2つの異なるサブ関数を呼び出す場合、どちらもkwargs名を共有しますが、必ずしもargs値ではありません - そのような設定では私の目標はまだ可能ですか?

答えて

2

辞書を使用してキーワード引数を渡すことは、関数を呼び出すこととはまったく異なっています。関数自体には関係なく、それはどのように呼び出されたか、それらの引数を何らかの方法で取得します。言い換えれば

あなたの関数が実際に必要としない場合は、

xy_dict = dict(x=data_one, y=data_two) 
try_dict_ops(**xy_dict) 

または

try_dict_ops(x=data_one, y=data_two) 

または

try_dict_ops(data_one, data_two) 

を使用した場合、機能を気にしませんがxy(sでそれらを渡すの唯一の目的は推移関数呼び出しにそれらを通過させることであるO)そしてちょうど**kwargsキャッチオールでこれらの引数をキャプチャ:今すぐtry_nested_dict_ops()に渡されたすべての余分なキーワード引数が渡され

def try_nested_dict_ops(a, b, **kwargs): 
    g = [try_dict_ops(**kwargs)[i] * a + b for i in range(len(x))] 
    return np.array(g) 

try_dict_ops()コールに、関数そのものが何であるかを知る必要はありません。これを複数の関数呼び出しに使用できます。

次に、xyが、位置引数としてではなくキーワード引数として渡されることを要求します。

+0

非常に便利です、ありがとうございます!すぐに、関数が複数の辞書から呼び出し可能なkwargsを持つことは可能ですか? – mikey

+0

@mikey再び、呼び出しに使用した同様の構文と関数パラメータの定義を混同しないでください。 Python 3.5では、呼び出し時に '** name'で複数の辞書を指定することができます。すべてのキー値が結合されて関数に渡されます。明示的にパラメータおよび/またはcatch-allパラメータを指定している場合は、関数に依存します。 –

関連する問題