関数を作っていると、「引数の数を決めうちにしたくない」「あとから引数を増やしたい」と感じる場面がありますよね。たとえば「渡された数値をぜんぶ合計する関数」を作りたいとき、引数を固定してしまうと不便です。そんなときに活躍するのが、Pythonの可変長引数である *args と **kwargs です。
この記事では、可変長引数の基本から、*args(位置引数をまとめて受け取る)と **kwargs(キーワード引数をまとめて受け取る)の違い、引数を書く順番、呼び出し側でのアンパックまで、実際に動くコードを交えながら初心者向けに丁寧に解説します。読み終えるころには、柔軟で再利用しやすい関数が書けるようになりますよ。
コンテンツ
可変長引数とは?
可変長引数とは、その名のとおり「個数が決まっていない引数」を受け取るしくみのことです。通常の関数は def add(a, b): のように引数の数が固定ですが、可変長引数を使うと、0個でも100個でも同じ関数で受け取れるようになります。
可変長引数には2種類あります。位置引数(順番で渡す引数)をまとめて受け取る *args と、キーワード引数(名前付きで渡す引数)をまとめて受け取る **kwargs です。それぞれ順番に見ていきましょう。なお、関数の基本的な書き方があいまいな方は、先に関数の基礎を解説した記事を読んでおくと理解がスムーズです。
*args の使い方(位置引数をまとめて受け取る)
仮引数の前にアスタリスク(*)を1つ付けると、渡された位置引数をすべてまとめて受け取れます。慣例として名前は args がよく使われますが、名前自体は自由です(大切なのは先頭の * です)。まずは「渡された数値を合計する関数」を作ってみましょう。
def add(*args):
total = 0
for n in args:
total += n
return total
print(add(1, 2, 3)) # 6
print(add(10, 20, 30, 40)) # 100
print(add()) # 0引数を3個渡しても4個渡しても、さらには1個も渡さなくても、同じ関数で処理できています。これが可変長引数の便利なところです。
args の正体はタプル
*args で受け取った値は、タプルとしてまとめられます。実際に型を確認してみましょう。
def show(*args):
print(type(args))
print(args)
show(1, 2, 3)
# <class 'tuple'>
# (1, 2, 3)このように args はタプルなので、for でループしたり、args[0] のようにインデックスでアクセスしたりできます。タプルそのものの性質についてはタプル(tuple)の使い方を解説した記事もあわせて読むと理解が深まります。
**kwargs の使い方(キーワード引数をまとめて受け取る)
仮引数の前にアスタリスクを2つ(**)付けると、name="佐藤" のような「名前付きの引数(キーワード引数)」をまとめて受け取れます。こちらも慣例で kwargs(keyword arguments の略)という名前がよく使われます。
def profile(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
profile(name="佐藤", age=25, job="SE")
# name: 佐藤
# age: 25
# job: SE渡したキーワード引数が、そのままキーと値のペアとして扱われているのが分かりますね。
kwargs の正体は辞書
**kwargs で受け取った値は、辞書(dict)としてまとめられます。
def show(**kwargs):
print(type(kwargs))
print(kwargs)
show(a=1, b=2)
# <class 'dict'>
# {'a': 1, 'b': 2}辞書なので、kwargs.items() でループしたり、kwargs.get("age") で値を取り出したりできます。辞書の操作に不安がある方は辞書(dict)の使い方を解説した記事も参考にしてみてください。
通常の引数と組み合わせる(引数を書く順番)
可変長引数は、通常の引数といっしょに使うこともできます。ただし、書く順番には決まりがあります。「通常の引数 → *args → **kwargs」の順に並べる必要があり、これを守らないとエラーになります。
def func(a, b, *args, **kwargs):
print("a =", a)
print("b =", b)
print("args =", args)
print("kwargs =", kwargs)
func(1, 2, 3, 4, x=10, y=20)
# a = 1
# b = 2
# args = (3, 4)
# kwargs = {'x': 10, 'y': 20}最初の2つ(1, 2)が a・b に入り、残りの位置引数(3, 4)が args に、名前付きの引数(x, y)が kwargs に振り分けられました。役割ごとにきれいに分かれるのがポイントです。
呼び出し側の * と **(アンパック)
ここまでは関数を「定義する側」の話でしたが、* と ** は関数を「呼び出す側」でも使えます。リストやタプルの前に * を付けると、要素がバラバラの位置引数として展開(アンパック)され、辞書の前に ** を付けると、キーワード引数として展開されます。
numbers = [1, 2, 3]
print(add(*numbers)) # 6
user = {"name": "田中", "age": 30, "job": "SE"}
profile(**user)
# name: 田中
# age: 30
# job: SEリストや辞書に入っているデータを、そのまま関数の引数として渡せるのでとても便利です。この「アンパック」という考え方についてはリストのアンパックを解説した記事でも詳しく紹介しています。
実用例:柔軟な関数を作る
*args と **kwargs を組み合わせると、状況に応じて引数の数が変わるような、柔軟な関数を作れます。たとえば、メイン料理・サイド料理(複数)・オプション(名前付き)を受け取る注文関数はこう書けます。
def order(main, *sides, **options):
print(f"メイン: {main}")
if sides:
print("サイド:", ", ".join(sides))
for key, value in options.items():
print(f"{key} → {value}")
order("ハンバーグ", "サラダ", "スープ", drink="コーヒー", size="大盛り")
# メイン: ハンバーグ
# サイド: サラダ, スープ
# drink → コーヒー
# size → 大盛りサイドが何品でも、オプションが何個でも、1つの関数で受け止められます。ライブラリの関数がさまざまなオプションを受け取れるのは、まさにこのしくみが使われているからです。
よくあるエラーと注意点
可変長引数でつまずきやすいポイントをまとめておきます。まず、引数の順番を間違えて def func(**kwargs, a): のように書くと SyntaxError になります。必ず「通常の引数 → *args → **kwargs」の順を守りましょう。
また、*args はタプル、**kwargs は辞書である点を忘れると、存在しないメソッドを呼んでエラーになりがちです。args に対して .items() を呼んだり、kwargs に対して append() を呼んだりしないよう注意してください。名前は args・kwargs でなくても動きますが、他の人が読んだときに分かりやすいので、特別な理由がなければ慣例に従うのがおすすめです。
もっと効率的にPythonを学びたい人へ
可変長引数のように、Pythonには「知っていると一気に便利になる」文法がたくさんあります。独学でも学べますが、つまずいたときにすぐ質問できる環境があると、挫折せずに一気に上達できます。
未経験からPythonを本格的に習得して、エンジニア転職まで目指したい方には、マンツーマン指導が受けられるプログラミングスクールという選択肢もあります。プロ講師にコードを直接見てもらえるので、独学では気づきにくい「書き方のクセ」も早い段階で直せます。まずは無料カウンセリングで、自分に合う学び方を相談してみるのも良いですよ。
※本記事には広告(アフィリエイトリンク)を含みます。
Pythonプログラミング|マンツーマンレッスンで初めてをプロに育てる【Python Winner】![]()
まとめ
今回は、Pythonの可変長引数 *args と **kwargs について解説しました。最後に要点を振り返っておきましょう。
*args:任意の個数の位置引数をまとめて受け取り、タプルになる**kwargs:任意の個数のキーワード引数をまとめて受け取り、辞書になる- 引数を書く順番は「通常の引数 → *args → **kwargs」を守る
- 呼び出し側でも
*リスト・**辞書でアンパックして渡せる - 名前は自由だが、慣例の
args・kwargsを使うと読みやすい
可変長引数を使いこなせると、柔軟で再利用しやすい関数が書けるようになります。ぜひ実際に手を動かして、いろいろな引数を渡して試してみてくださいね。
ナノトイラボ 