HOWTO · Python

Python で Kwargs を別の関数に渡す

Pythonのキーワード引数と、`**kwargs`で引数を辞書にまとめて別の関数に渡す方法を解説します。

このページの内容

Pythonでキーワード引数の辞書を別の関数に渡すには、display(**details)のように**mappingを付けて呼び出します。Pythonは各キーと値の組み合わせを、名前付き引数として展開します。また、関数の**kwargsパラメーターで任意の数のキーワード引数を受け取り、同じ方法で別の関数に渡せます。

Pythonのキーワード引数

キーワード引数は、関数呼び出しで値とパラメーター名を対応付けます。それぞれをname=valueの形で記述します。たとえば、greet(first="Anne", age=27)では、名前を指定して値を渡します。関数にはその名前を受け取るパラメーターが必要です。値は呼び出し時の位置にかかわらず、対応するパラメーターに割り当てられます。

関数に複数のパラメーターがある場合、この書き方にすると呼び出しを読み取りやすくなります。また、デフォルト値のあるパラメーターはそのままにして、任意のパラメーターだけを指定できます。キーワード引数の名前は関数のパラメーター名と一致させる必要があります。ただし、関数が**kwargsで追加のキーワード引数を受け取る場合はその限りではありません。

Pythonで**kwargsを使って関数を呼び出す

関数定義でパラメーター名の前に**を付けると、個別の名前付きパラメーターに対応しないキーワード引数をまとめて受け取れます。このパラメーターには慣例としてkwargsという名前が使われますが、有効な変数名であれば別の名前でも構いません。関数内では、受け取った値を辞書として利用できます。

たとえば、def describe(**kwargs): ...は、describe(name="Rabbit", sound="squeak")のような呼び出しを受け取れます。このとき作られる辞書には2つの項目があり、nameには"Rabbit"、soundには"squeak"が対応します。この方法なら、関数のシグネチャに個々の選択肢を列挙せずに、名前付きのオプションを受け取れます。関数内で辞書の値を調べたり、必要な値を選んだり、別の関数に渡したりできます。

*argsも似た目的で使いますが、こちらは位置引数を受け取り、タプルにまとめます。位置引数には*args、キーワード引数には**kwargsを使います。位置引数をまとめるための表記は**argsではありません。

Pythonで**kwargsを別の関数に渡す

関数呼び出しで辞書名の前に**を付けると、その辞書を別の関数に渡せます。例では、infoがdetailsを受け取り、infoからshow_detailsを呼び出すときに展開します。呼び出された関数は、自身の**kwargsパラメーターを通じて、辞書の項目を名前付き引数として受け取ります。

def show_details(**kwargs):
    for key, value in kwargs.items():
        print(key, value)


def info(**kwargs):
    show_details(**kwargs)


details = {"name": "Shen", "age": 27, "degree": "SE"}
info(**details)
name Shen
age 27
degree SE

info(**details)を呼び出すと、マッピングの項目がinfoへのキーワード引数として展開されます。infoはそれらをローカルなkwargs辞書に集め、show_details(**kwargs)は次の呼び出しで同じ項目を展開します。ループは各キーと値を表示します。出力例では、nameがShen、ageが27、degreeがSEと表示されます。これらのキー名やラベルは、コードと出力ブロックにある英語表記のままです。辞書のキーは、呼び出し先の関数が受け付ける名前に合わせてください。明示的なパラメーターが定義されている場合、各キーはそのいずれかに一致するか、関数の**kwargsパラメーターで受け取れる必要があります。

転送する関数は、あらかじめ個々のキーを知っている必要はありません。このパターンは、呼び出し元から渡されたオプションを引き継ぎながら、別の呼び出しの前後に処理を加えるラッパーに役立ちます。ラッパーに明示的なパラメーターもある場合は、シグネチャでそれらを**kwargsより前に定義し、必要なキーワード引数だけを転送します。

まとめ

通常のキーワード引数を渡すにはname=valueを使い、関数定義の**kwargsで追加のキーワード引数を辞書にまとめ、関数呼び出しの**mappingで辞書を展開して別の関数に渡します。位置引数には*argsを使います。確実に転送するには、マッピングのキーを呼び出し先が受け付けるパラメーター名に合わせます。