Pythonの関数呼び出しにおいて、辞書(dict)に格納されたデータを「キーワード引数」として関数にまとめて渡す機能があります。
これにはアスタリスクを2つ重ねた ** を使用します。リストやタプルを位置引数として展開する * と対になる機能です。
この記事では、辞書をキーワード引数として展開する方法と、位置引数の展開(*)と組み合わせる方法について解説します。
キーワード引数の展開(辞書のアンパック)
関数を呼び出す際、辞書の前に ** を付けると、その辞書の「キー」が引数名、「値」が引数の値として展開され、関数に渡されます。
構文:
関数名(**辞書変数)
これは 関数名(キー1=値1, キー2=値2, ...) と記述するのと等価です。
具体的な使用例
例として、APIへのリクエスト情報を表示する関数を使用します。この関数は endpoint, method, timeout という3つの引数を必要とします。
def request_api(endpoint, method, timeout):
"""APIリクエストのパラメータを表示する関数"""
print(f"接続先: {endpoint}")
print(f"メソッド: {method}")
print(f"タイムアウト: {timeout}秒")
print("--- リクエスト送信 ---")
# リクエスト設定が辞書としてまとまっている場合
request_config = {
"method": "GET",
"timeout": 30,
"endpoint": "https://api.example.com/v1/users"
}
# ** を付けて辞書を展開して渡す
# キーの順番は引数の順番と一致していなくても問題ない
request_api(**request_config)
実行結果:
接続先: https://api.example.com/v1/users
メソッド: GET
タイムアウト: 30秒
--- リクエスト送信 ---
重要な注意点:キーと引数名の一致
この方法を使用する場合、辞書のキーは関数の引数名と完全に一致している必要があります。もし、関数定義に存在しない引数名が辞書のキーに含まれていると、TypeError が発生します。
invalid_config = {
"endpoint": "https://api.example.com",
"method": "POST",
"timeout": 30,
"retry": 3 # 関数には 'retry' 引数がない
}
# エラーになる
# request_api(**invalid_config)
# TypeError: request_api() got an unexpected keyword argument 'retry'
(ただし、関数側が **kwargs で可変長引数を受け取るように定義されていればエラーにはなりません。)
位置引数の展開(*)とキーワード引数の展開(**)の併用
リストの展開(*)と辞書の展開(**)は、一つの関数呼び出しの中で同時に使用できます。
この場合、定義順序と同様に、**先に位置引数(*)、後にキーワード引数(**)**を記述する必要があります。
構文:
関数名(*リスト変数, **辞書変数)
具体的な使用例
サーバーのログを出力する関数を例にします。必須の情報(タイムスタンプ、レベル)はリストで、詳細な属性は辞書で管理されているケースです。
def system_logger(timestamp, level, user=None, ip=None):
"""ログを出力する関数"""
print(f"[{timestamp}] {level}")
print(f" User: {user}")
print(f" IP: {ip}")
# 基本情報(リスト)
base_info = ["2025-11-20 15:30:00", "WARNING"]
# 詳細情報(辞書)
context = {
"user": "admin",
"ip": "192.168.10.5"
}
# リストと辞書を同時に展開して渡す
system_logger(*base_info, **context)
実行結果:
[2025-11-20 15:30:00] WARNING
User: admin
IP: 192.168.10.5
base_info の要素が timestamp と level に割り当てられ、context の要素が user と ip に割り当てられました。
まとめ
- 関数呼び出し時に辞書の前に
**を付けると、キーワード引数として展開されます。 - 辞書のキーは、関数の引数名と一致している必要があります(キーは文字列である必要があります)。
func(*list, **dict)のように記述することで、位置引数の展開とキーワード引数の展開を併用できます。
設定ファイル(JSONなど)から読み込んだ辞書データを、そのまま処理関数の引数として流し込む際などに非常に有効なテクニックです。
