概要
Pythonにおける *
および **
は、関数引数の展開だけでなく、
タプル・辞書の展開、リストの結合、キーワード引数の委譲 など、柔軟かつ構造的な設計を可能にする構文要素である。
本稿では、*args
/ **kwargs
の基本から、現場での応用と「束縛操作」への拡張的使用までを網羅的に解説する。
1. 基本:引数の展開と受け取り
✅ 可変長引数(受け取り)
def func(*args, **kwargs):
print(args) # タプルになる
print(kwargs) # 辞書になる
func(1, 2, 3, a=10, b=20)
# → args = (1, 2, 3)
# → kwargs = {'a': 10, 'b': 20}
✅ 引数の展開(呼び出し)
def greet(name, age):
print(f"{name} is {age} years old.")
info = ("Alice", 30)
greet(*info) # タプルを展開して渡す
params = {"name": "Bob", "age": 25}
greet(**params) # 辞書をキーワード引数として展開
2. データ構造への応用:リスト結合や辞書合成
a = [1, 2]
b = [3, 4]
print([*a, *b]) # → [1, 2, 3, 4]
base = {'x': 1, 'y': 2}
override = {'y': 99, 'z': 100}
merged = {**base, **override}
# → {'x': 1, 'y': 99, 'z': 100}
→ 順序を制御することで意図的な上書きや差し替えが可能
3. 関数の委譲・ラッパーでの利用
def log_and_call(fn, *args, **kwargs):
print(f"Calling {fn.__name__} with {args} {kwargs}")
return fn(*args, **kwargs)
def multiply(x, y):
return x * y
log_and_call(multiply, 3, 4) # → 12
→ デコレータやラッパー関数でも頻出
→ 汎用的な関数呼び出しの抽象化が可能になる
4. 応用的な束縛:アンパックと同時に分解
head, *body, tail = [1, 2, 3, 4, 5]
# head = 1, body = [2, 3, 4], tail = 5
→ 「中央を保持したまま両端を切り出す」といった構造も一行で表現可能
→ DSL的なコード構築やデータ操作の文脈で有用
5. デフォルトと組み合わせた高度な引数設計
def api_call(method="GET", **options):
timeout = options.get("timeout", 10)
print(f"{method=}, {timeout=}, {options=}")
api_call(url="/users", timeout=30, headers={"Auth": "token"})
→ 柔軟な関数設計と 将来の拡張性を両立できる構造
よくある誤解と対策
❌ *args
/ **kwargs
は雑に使うと読みづらい
→ ✅ 正しい。関数の目的が明確な場合は、明示的な引数が推奨される。
→ ただし、ラッパー/中継関数では拡張性・再利用性を大きく高める
❌ 展開できるのは関数呼び出し時だけ
→ ✅ 実際には、リスト・タプル・辞書合成にも広く使える汎用構文
❌ Python初心者向けの構文
→ ✅ むしろ中・上級者ほど積極的に使いこなす構文。
→ 設計パターンや内部DSLでも多用される
結語
アンパック構文(*
, **
)は、
Pythonにおける**「動的・柔軟な関数設計」および「データ構造の展開と合成」を支える構文基盤**である。
-
*args
,**kwargs
→ 汎用的な引数設計 -
*iterable
,**dict
→ 構造をそのまま展開可能 -
head, *body, tail
→ 中央を保持した分割
アンパックとは、“構造の一体性を崩すことなく再構成するための宣言的な言語構文”である。