LoginSignup
4
2
はじめての記事投稿

*args, **kwargsとはいったい何なのか

Posted at

背景

Pythonコードを書いていると関数に*args, **kwargsという引数を使う場面に出くわすと思います。

初見だと一体これは何をやっているの??と感じたため、まとめてみます。

本文

*args, **kwargsとは何なのか?結論

引数の大きさを自由に変更できる引数のこと

詳しく説明します。引数が固定長の場合、例えば2つの入力のみ想定していたが、3つや4つの入力の合計を出力したいとなった時、新たに3引数、4引数の関数を作るのは面倒ですよね。

そこで*argsや**kwargsが登場します。

*argsでは複数の引数をタプルとして受け取り、**kwargsでは複数のキーワード引数を辞書として受け取ります。これらは可変長引数と呼ばれているので覚えておきましょう。

ちなみにargsとかkwargsって何なの?って思う方いると思います。おそらくですが、
args: argments
kwargs: keywords argments
の略だと思います。知っている方いらっしゃれば教えてください。

それではサンプルコードを見てみます。

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

print(num_sum(1, 2, 3))
# 6
print(num_sum(1, 2, 3, 4, 5, 6))
# 21

def func_kwargs(**kwargs):
    print('kwargs: ', kwargs)

func_kwargs(key1=1, key2=2, key3=3)
# kwargs:  {'key1': 1, 'key2': 2, 'key3': 3}

確かに引数を何個も受け取れてますね。非常に便利な機能であることが分かります。

注意点

可変長引数は非常に便利な機能ですが、何でも使えばいいわけではありません。具体的に問題例を見てみます。

class User:
    def __init__(self, **kwargs):
        self.name = kwargs['name']
        self.mail = kwargs.get('mail')

user = User(name="hoge", address="hogehoge") # エラーが起きない

print(user.mail)
# None

上記のコードでは、クラスが期待していないaddress=も引数として受け取れてしまいます。さらにuser.mailはNoneになるため、別のプログラム上でエラーになる可能性があります。

実用を考えると注意が必要ですね。

もう一つ例を見てみます。

def hoge(a, b, *args):
    print(a)
    print(b)
    print(args)

a="Hello!"
b="World!"
c=["I am a", "nooby", "programmer!!"]

hoge(a,b,c)
# Hello!
# World!
# (['I am a', 'nooby', 'programmer!!'],)

可変長引数は位置引数と組み合わせることもできます。この場合、位置引数より後ろ側で指定した値がargsにタプルとして渡されます。

この時、位置引数のみ記述すればどうなるでしょうか。

hoge(a, c)
# Hello!
# ['I am a', 'nooby', 'programmer!!']
# ()

argsには空のタプルが入力されています。これは可変長引数が自由な長さを持てることにより起こります。エラーの原因になりそうですね。

このままだとよくないので解決策として、

def hoge(a,b,*args):
    if len(args)==0: raise TypeError("args is not given") # argsがタプル型なのを利用する
    print(a)
    print(b)
    print(args)

a="Hello!"
b="World!"
c=["I am a","nooby","programmer!!"]

hoge(a,c)
# TypeError: args is not given

こうすることで引数が想定より少ないとき、エラーコードを出力できるようになりました。

参考サイト

https://note.nkmk.me/python-args-kwargs-usage/
https://itstudio.co/2019/08/05/9454/#toc10
https://pg-chain.com/python-function-args
https://jisou-programmer.beproud.jp/関数設計/9-関数の引数に可変長引数を乱用しない.html
https://qiita.com/heat_exchange/items/ad730e02f429992b06dd

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2