Pythonの引数*args, **kwargsとは?その解説

Pytonの*args(可変長位置引数)と**kwargs(可変長キーワード引数)ついてわかりやすくその基本を解説

今回のPython初心者・入門者向け解説は、Pythonの関数の引数でよく登場する謎の用語、「*args」と「**kwargs」について説明です。

これらはそれぞれ、可変長位置引数、そして可変長キーワード引数と呼ばれます。名前のとおり位置引数とキーワード引数の仲間なので、まずはそもそも位置引数とキーワード引数がどのようなものかを理解しておくことがおすすめです。

それらについては以下の記事で解説しておいたので、こちらを御覧ください。

さて、今回の*argsと**kwargsですが、それぞれ一体どのようなものなのでしょうか。順番にみていきましょう。

*args(可変長位置引数)について

使い方

さっそく*args(可変長位置引数)を使った簡単なコードを見てください。

def hello(*args):  # 「*」をつけてる
    print(f'{args}さん、こんにちは')  # 「*」はここでは不要

hello('Tom')

これを実行すると、

('Tom',)さん、こんにちは

となります。

ここで注目は、

名前を格納している変数の部分が、タプル形式の出力になっている点です。

タプルとは、

(要素1, 要素2, 要素3,・・・)

といった形で表現されるデータです。括弧の種類に注意しましょう。

タプル(要素1, 要素2, 要素3,・・・ )
リスト[要素1, 要素2, 要素3,・・・ ]
辞書{要素1, 要素2, 要素3,・・・ }
括弧の種類に注意

この出力されたタプル形式の時点ですでにお気づきかもしれませんが、そうです。この*args(可変長位置引数)は複数の要素をもつことが可能です。それら複数の要素を1つにまとめたものです。

実際に実引数において、指定する要素を増やしてみましょう。Tom以外に、NancyとAlbertを追加します。

def hello(*args):
    print(f'{args}さん、こんにちは')

hello('Tom')  # ここまでは上のコードと同じ
hello('Tom', 'Nancy', 'Albert')  # 新しく加えた部分

こうすると、実行結果は、

('Tom',)さん、こんにちは
('Tom', 'Nancy', 'Albert')さん、こんにちは

と、このようになります。

実引数のところで要素の数(引数の数)を増やしても、*argsはそれらを全てうまく1つにまとめてくれています。これが「可変長」という言葉の意味ですね。

実際に、argsの長さを表示させてみましょう。上のコードを少しいじります。

def hello(*args):
    print(f'{args}さん、こんにちは')
    print(len(args))  # タプルargsにある要素の数を表示

hello('Tom')
hello('Tom', 'Nancy', 'Albert')

こうすると、結果は、

('Tom',)さん、こんにちは
1
('Tom', 'Nancy', 'Albert')さん、こんにちは
3

のように、argsの長さが1と3と出力されます。「長さ」が「可変」であることがわかりますね。

「args」の名前は変えてOK

この可変長位置引数は、いろいろなPython解説サイト(公式ドキュメント含む)で、「*args」と書かれて使われていますが、実際には「args」という仮引数名は変更しても大丈夫です。

実際に、「*args」を「*name」に変えてみましょう。

def hello(*name):
    print(f'{name}さん、こんにちは')

hello('Tom')  # ここまでは上のコードと同じ
hello('Tom', 'Nancy', 'Albert')  # 新しく加えた部分

結果は、

('Tom',)さん、こんにちは
('Tom', 'Nancy', 'Albert')さん、こんにちは

と、「*args」の場合と全く同じになります。

それでは次にこのような可変長位置引数を使うメリットを考えてみましょう。

可変長位置引数を使うメリットとは?

まず上のようにTom、Nancy、Albertの3人を使って、同じような結果になるコードを、可変長位置引数を使わずに書いてみましょう。次のようにするのが基本中の基本でしょうか。

def hello(name_one, name_two, name_three):
    print(f'({name_one}, {name_two}, {name_three})さん、こんにちは')

hello('Tom', 'Nancy', 'Albert')

実引数で3つの名前を使うので、関数宣言時の仮引数でも3つの仮引数を指定しました。

今回は名前が3つでしたが、これが10個になったら・・・実引数で10個書くのはいいとして、仮引数も10個作ります?実にめんどくさくなりますね。単純に手間が倍です。

このように、関数宣言時の仮引数で可変長位置引数を使っておくと、実引数の部分だけ変更すれば良いということになるので、省エネ(?)が実現できます。

**kwargs(可変長キーワード引数)について

さて、上述の*args(可変長位置引数)が理解できれば、あとは**kwargs(可変長キーワード引数)の理解も簡単です。キーワード形式になるだけです。(kwargs = keyword + args)

アスタリスク(*)が2つ(**)になるのでそこは注意しましょう。

使い方

実引数はキーワード形式で指定しますので

キーワード = 対応するデータ

という形で書いていきます。簡単にキーワードを使った辞書の作り方を復習しておきましょう。

a = dict(one=1, two=2, three=3)  # 新しい辞書オブジェクトaを作成
print(a)  # 結果:{'one': 1, 'two': 2, 'three': 3}

これを踏まえて、次のコードを見てください。

def hello(**kwargs):  # 「**」をつけてる
    print(f'{kwargs}さん、こんにちは')  # 「**」はここでは不要

hello(name_one='Tom', name_two='Nancy', name_three='Albert')

これを実行すると、

{'name_one': 'Tom', 'name_two': 'Nancy', 'name_three': 'Albert'}さん、こんにちは

となります。{ }で囲まれたところはまさに辞書形式ですね。

実引数のところでは「=」(イコール)を使った指定ですが、結果ではそのイコールが「:」(コロン)になっています。

先ほどの*args(可変長位置引数)ではタプル形式が使われたものでしたが、今回は辞書形式のものが使われた実行結果になっています。

もちろんこの**kwargsにおける「kwargs」という名前についても、上述の*argsの場合と同様に自由に変更が可能です。

たとえば、kwargsをname_dictに変更してみましょう。

def hello(**name_dict):  # 「**」をつけてる
    print(f'{name_dict}さん、こんにちは')  # 「**」はここでは不要

hello(name_one='Tom', name_two='Nancy', name_three='Albert')

結果は、

{'name_one': 'Tom', 'name_two': 'Nancy', 'name_three': 'Albert'}さん、こんにちは

kwargsを使ったのと同じです。

*argsと**kwargsを同時に使う場合の注意点

*args(可変長位置引数)と**kwargs(可変長キーワード引数)は同時に使うことができます。しかし、注意点があります。それはどちらを先に書くかという順番です

この点、Pythonでは「**」を使った引数は必ず、引数リストの一番最後に書かなければなりません。

すなわち、

def 関数(仮引数1, 仮引数2, *仮引数3, **仮引数4)

は正しいですが、

def 関数(仮引数1, 仮引数2, **仮引数3, *仮引数4)

はエラーとなります。

プログラミングを学びIT業界へ転職するなら現役エンジニアから学べるプログラミングスクールTechAcademy [テックアカデミー]でオンライン講座を受講するのが良いと思います。1人で悩みながら学習を進めるよりもわかりやすく、費やす時間も少なく合理的・効率的に学習できるからです。

など各種の講座が用意されています。無料で体験できるテックアカデミー無料体験も用意されています。

2 Comments

Comments are closed.