8ヶ月ぶりのQiita投稿。
最近は「この条件のときどう動くんだっけ?」といった疑問と検証で手が止まることが多い月歩人です。
今回はその中から「Pythonのキーワード引数」に焦点を当てたいと思います。
Pythonのキーワード引数とは
>>> def f(a, b):
... print(a, b)
...
>>> f(a=1, b=2) <------ コレ
1 2
関数に指定されている引数名を、関数呼び出し時に指定することで引数を明示するものです。
この辺りは使用することが多いので割愛します。
今回の記事はよくキーワード引数のところで見る**
(アスタリスク2つ)について焦点を当てましょう
よく見る**kwargsの正体
(私はkwargsをケーワーグス
と読んでいますが、この辺は論争が起きそうなのであまり触れないようにします)
Pythonのワイルドなキーワード引数にはよくkwargs
が出てきますが、この引数名自体に意味はありません。
**
が2つついた引数は、キーワード引数を何でも受け入れるという引数になるので、**hoge
や**huga
でも良いのです。
分かりやすいようにパターン別のコードを用意しました。
関数の引数に**
が指定してある場合
>>> def f(**kwargs):
... print(kwargs)
...
>>> f(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}
このように、関数に**
を用いた引数を用意した場合、呼び出し元のキーワード引数に制限がなくなり、関数へ送った引数は辞書で格納されます。
しかし**
の動きはこれだけではありません。
関数呼び出し時に**
を指定する場合
>>> def f(a, b):
... print(a, b)
...
>>> f(a=1, b=2)
1 2
>>> f(**{'a': 1, 'b': 2}) <------- 等価
1 2
辞書に**
をつけて渡すことで、関数で指定されたキーワード引数に展開することができます。
関数呼び出し時と関数の引数に**
を指定している場合
>>> def f(**kwargs):
... print(kwargs)
...
>>> f(**{'a': 1, 'b': 2})
{'a': 1, 'b': 2}
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
動きとしては
{'a': 1, 'b': 2}がキーワード引数に展開された!
-
**kwargs
がキーワード引数を辞書に収束した! - kwargsという辞書が出来上がった!
という感じでしょうか。
他に番外として安易に**
を使って失敗したor**kwargs
がゲシュタルト崩壊する例を以下に記載します。
関数呼び出し時に**
を指定したのに関数の引数に**
がなかった場合
>>> def f(kwargs):
... print(kwargs)
...
>>> f(**{'a': 1, 'b': 2})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'a'
関数呼び出し時に**
を指定していないが関数の引数に**
を指定した場合
>>> def f(**kwargs):
... print(kwargs)
...
>>> f({'a': 1, 'b': 2})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
>>> f(a=1, b=2)
{'a': 1, 'b': 2}
いかがでしたか?
**kwargs
がゲシュタルト崩壊したあなたは正解。
とはいえ**
はPythonの開発でとてもお世話になるので混乱しない程度に動きを理解しておきましょう!
忘れた場合はこちらの記事へ。忘れないようにストックといいねとお願いします。