Python の *args と **kwargs を完全理解する

*args と **kwargs を使うと、関数が任意の数の引数を受け取れるようになります。ラッパー関数やデコレータを書く際に必須の知識です。

*args:任意個の位置引数

*args はタプルとして位置引数を受け取ります。

def sum_all(*args):
    return sum(args)

print(sum_all(1, 2, 3))       # 6
print(sum_all(1, 2, 3, 4, 5)) # 15

**kwargs:任意個のキーワード引数

**kwargs は辞書としてキーワード引数を受け取ります。

def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

print_info(name="Alice", age=30, city="Tokyo")

組み合わせて使う

両方を同時に使う場合、順序は「位置引数 → *args → キーワード引数 → **kwargs」です。

def func(a, b, *args, option=None, **kwargs):
    print(f"a={a}, b={b}")
    print(f"args={args}")
    print(f"option={option}")
    print(f"kwargs={kwargs}")

func(1, 2, 3, 4, option="test", extra="value")

呼び出し時のアンパック

リストやタプルは * で、辞書は ** でアンパックして渡せます。

def greet(name, age):
    print(f"{name} is {age} years old")

data = {"name": "Bob", "age": 25}
greet(**data)  # Bob is 25 years old

args = ["Alice", 30]
greet(*args)   # Alice is 30 years old

デコレータのラッパー関数では def wrapper(*args, **kwargs) と書くことで、どんな引数の関数にも対応できます。