*args と は、関数がの引数を受け取れるようにします。 は余分な引数をタプルにまとめ、 は余分な引数を辞書にまとめます。(名前は慣習であり、重要なのは と です。)
**kwargs*args**kwargs***def total(*args): # collects all positional args into a tuple
print(args) # e.g. (1, 2, 3)
return sum(args)
total(1, 2, 3) # 6
total(1, 2, 3, 4, 5) # 15 — any number of args
def configure(**kwargs): # collects keyword args into a dict
print(kwargs) # e.g. {"host": "localhost", "port": 8080}
for key, value in kwargs.items():
print(f"{key} = {value}")
configure(host="localhost", port=8080, debug=True)
def func(a, b, *args, **kwargs):
# a, b → required positional
# args → extra positional (tuple)
# kwargs → extra keyword (dict)
...
func(1, 2, 3, 4, x=5, y=6)
# a=1, b=2, args=(3, 4), kwargs={"x": 5, "y": 6}
必須の順序は、通常のパラメータ、次に *args、最後に **kwargs です。
# `*` and `**` also UNPACK collections INTO arguments at the call site
numbers = [1, 2, 3]
total(*numbers) # same as total(1, 2, 3)
settings = {"host": "x", "port": 80}
configure(**settings) # same as configure(host="x", port=80)
同じ構文で list/dict を位置引数/キーワード引数にアンパックできます。引数の転送に便利です。
def wrapper(*args, **kwargs):
# accept ANY arguments and pass them through unchanged
return original_func(*args, **kwargs)
このパススルーのパターンは、decorator や wrapper 関数が任意の関数シグネチャを扱う方法です。
*args/**kwargs は、任意の個数の引数を受け取れる柔軟な関数シグネチャを実現します。汎用ユーティリティや wrapper、とりわけ decorator(未知のシグネチャの関数を *args, **kwargs でラップする必要がある)を書くために不可欠です。
アンパックの方向(*list、**dict)も、引数の転送や展開に同様に役立ちます。
まとめる側とアンパックする側の両方を理解することは、再利用可能で汎用的な Python コードを書くため、そしてこれらの機能に依存する多くのライブラリ API や decorator を読むために鍵となります。