Pythonの可変長引数*argsと*kwargsの使い方と違いを分かりやすく解説
この記事では、Pythonの関数で可変長引数を受け取る方法について解説します。Pythonには可変長引数を受け取る方法として*args
と**kwargs
がありますが両者には使い方に違いがあります。可変長引数はたまにしか使わないので構文を忘れがちです。この記事では、*args
と**kwargs
の利用方法を再確認できるようにしました。
可変長引数の種類とルール
以下、可変長引数の使い方のメモになります。まずは、以下のルールを理解しましょう。
可変長位置引数(*args
)と可変長キーワード引数(**kwarg
)が存在
*args
と**kwargs
の違い*args
は任意の数の引数をタプルとして受け取る**kwargs
は、任意の数のキーワード引数を辞書として受け取る
*args
と**kwargs
を両方同時に利用する場合の制約両方同時使うことができるが、*args
が**kwargs
の前になければならない
つまり、*args→**kwargsの順番である必要がある
特に注意するのは、両方を同時に利用する場合の順番です。*args→**kwargsでなければならないことに気をつけましょう。
可変長位置引数(*args)
*argsの基本的な使い方
可変長位置引数(*args
)を使うと任意の数の引数をタプルとして関数に渡すことが可能です。例のように、整数、文字列、リストなどさまざまな型を受け取ることができます。
def f(*args):
print(args)
for e in args:
print(e)
f(10, 20, "abc", [1, 2, 3])
# (10, 20, 'abc', [1, 2, 3])
# 10
# 20
# abc
# [1, 2, 3]
なお、引数名は*argsでなくてもOKです。例えば、*element
に変更しても同様の結果になります(個人的には、分かりやすいように*argsをお勧めします)
def f(*elements):
print(elements)
for e in elements:
print(e)
f(10, 20, "abc", [1, 2, 3])
# (10, 20, 'abc', [1, 2, 3])
# 10
# 20
# abc
# [1, 2, 3]
*argsの応用例
例えば、任意個の数値を受け取って、平均値と最大値、最小値を取る関数などを作成することができます。
不特定数の引数(個数が決まっていない引数)を受け取って処理したい場合に便利です。
以下は、不特定数の値を受け取って、平均と最大値、最小値を返す例です。
def calc(*args) :
total = 0
nmin, nmax = args[0], args[0]
for i in args :
total += i
nmin = min(nmin, i)
nmax = max(nmax, i)
return total/len(args), nmin, nmax
print(calc(10,3,40,2))
# (13.75, 2, 40)
可変長キーワード引数(**kwargs)
**kwargsの基本的な使い方
可変長キーワード引数(**kwargs
)は、任意の数のキーワード引数を辞書として関数に渡すことができるものです。アスタリスクが2つ付いていれば、変数名はkwargs
でなくて構いません(こちらも、個人的には**kwargsという名前にしておくことをお勧めします)。
以下は、**kwargs
の例です。
def f(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
f(name="taro", age=30, sex="male")
# name: taro
# age: 30
# sex: male
*kwargsの応用例
可変長キーワード引数は、オプションなどを受け取る場合に便利です。
下記の例では、キーワードが存在する場合は、パラメータに代入し、存在しない場合は規定値を代入しています。
もう少し詳しくプログラムを解説すると、if xxx in kwargs
でxxx
が引数に含まれているか確認し、含まれていた場合には引数で指定された値をパラメータに代入しています。
def f(**kwargs):
name, age, sex = None, None, None
if "name" in kwargs:
name = kwargs["name"]
else :
name = "no name"
if "age" in kwargs:
age = kwargs["age"]
else :
age = "no age"
if "sex" in kwargs:
sex = kwargs["sex"]
else :
sex = "no sex"
print(name, age, sex)
f(name="taro", age=30, sex="male")
# taro 30 male
以上のように、可変長キーワード引数は、不特定数のパラメータを受け取る場合に便利です。
自身が処理できるパラメータだけ処理し、あとは他の関数に任せるパターン
関数がさらにパラメータを持った関数を呼び出す場合、以下のようなコードで実現することができます。
下記の例は、関数f
はパラメータname
だけを処理し、関数f
から呼び出された関数g
がage
とsex
を利用する例です。
可変長キーワード引数を使うと、それぞれの関数が受け取るパラメータを呼び出し側で一括して指定することができます。
def f(**kwargs):
print(kwargs["name"])
g(kwargs)
def g(kwargs):
print(kwargs["age"], kwargs["sex"])
f(name="taro", age=30, sex="male")
# taro
# 30 male
各関数が処理できるものだけを受け取り、他のパラメータは他の関数へ渡す形です。このような実装を行なっているライブラリが結構ある印象です。
*argと**kwargsを組み合わせる
*arg
と**kwargs
を組み合わせる場合、*args
を手前に記述する必要があります。
def f(*args, **kwargs):
op = "add"
if "op" in kwargs :
op = kwargs["op"]
tot = 0 if op == "add" else 1
for i in args :
if op == "add" :
tot += i
elif op == "mul" :
tot *= i
return tot
print(f(1,2,3,4, op="add"))
# 10
print(f(1,2,3,4, op="mul"))
# 24
まとめ
Pythonで可変長引数を利用する方法を説明しました。特に**kwargsは色々なライブラリでも使われているので可変長引数について理解していると、ライブラリの理解の助けになるかと思います。