可変長引数とは
可変長引数は関数の引数の個数を指定せず、引数を渡す方法です。
pythonでは引数名の前に*(アスタリスク)を付与することで可変長引数を指定することができます。
def func1(*val):
for value in val:
print('value:', value)
func1(1, 2, 3)
結果
value: 1
value: 2
value: 3
可変長引数を受け取った側での型を調べてみるとタプルであることがわかります。
def func2(*val):
print(type(val))
print('val:', val)
func2(1, 2, 3)
結果
<class 'tuple'>
val: (1, 2, 3)
それでは次のように可変長引数を受け取った関数(func4)から、別の可変引数を持つ関数(func3)を呼び出した場合はどうなるのでしょうか
def func3(*val):
print(type(val))
print('val:', val)
for value in val:
print('value:', value)
def func4(*val):
func3(val)
func4(1, 2, 3)
結果
<class 'tuple'>
val: ((1, 2, 3),)
value: (1, 2, 3)
func4が受け取った可変引数(タプル)をそのまま引き渡したため、func3ではタプルの入れ子になってしまっています。func3でも入れ子になっていない変数で受け取るにはどうすればよいのでしょうか。
これを解決するしてくれるのが__引数の展開__です。以下の様に受け取った可変引数に*(アスタリスク)を付与すると、可変引数を展開してくれるので
func3では単一のタプルの引数で受け取ることができます。
def func3(*val):
print(type(val))
print('val:', val)
for value in val:
print('value:', value)
def func4(*val):
func3(*val)
func4(1, 2, 3)
結果
<class 'tuple'>
val: (1, 2, 3)
value: 1
value: 2
value: 3
引数の展開
引数の展開では、リストやタプルの変数の中身をばらしてくれます。変数の先頭に*(アスタリスク)を付与することで引数の展開が行われます。(ディクショナリではキー項目のみ展開されます。)
li = [1, 2, 3]
tp = (4, 5, 6)
dic = {'a': 7, 'b': 8, 'c': 9}
print(*li)
print(*tp)
print(*dic)
結果
1 2 3
4 5 6
a b c
またアスタリスクを二つ付与するとキーワード可変引数に対して展開を行います。
こちらは、キーワード可変引数を受け取った関数から、別のキーワード可変引数を持つ関数を呼び出す際に重宝します。
def func5(**kwargs):
for k, v in kwargs.items():
print('key:', k, ', value:', v)
def func6(**kwargs):
func5(**kwargs)
func6(a=1, b=2, c=3)
結果
key: a , value: 1
key: b , value: 2
key: c , value: 3