01.本記事に書くこと
- 関数のパラメータに定義する
*
や**
の意味と、その使い方
時間が経ってしまっても素早く思い出せるように、ここに整理したいと思います。
02.*
と**
は可変長引数を受け取るパラメータにつけるものである
関数のパラメータに*args
や**kwargs
と書いてあるコードを見かけた。
これは可変長引数を受け取るパラメータに記述されるもので、関数呼び出し時にパラメータに渡す引数の数を、固定ではなく任意の数にできるようになる。
可変長引数とは、通常1つしか引数が指定できないところ、任意数の引数を指定できるようにしたもの。
〜普通はダンボール1つにつき1つの品物しか入れられない。
しかし、可変長引数ならば1つのダンボールにつき、いくらでも品物を入れることができる上に、それらは1枚のプチプチでパックされる。〜
def kansu(*args):
print(f'{args}を受け取った!')
kansu('Apple', 'Banana', 100)
# ('Apple', 'Banana', 100)を受け取った!
パラメータはargs
1つだけに対して、3つの引数を渡しているが、エラーなく動作している。
身近な例でいうと、print()関数
や.format()メソッド
でも可変長引数が用いられている。
print('a','b','c') # a b c
又、args
やkwargs
という名前は慣習的に用いられるものなので、好きな名前でも動作する。
def x(*z):
y = []
for i in z:
y.append(i*10)
print(y)
x(1,2,3,4,5,6,7,8)
# [10, 20, 30, 40, 50, 60, 70, 80]
03.*
が1つの時と2つの時の違い
可変長引数には2種類あり、それぞれ引数の渡し方や、受け取り方が異なる。
1.可変長位置引数を受け取るパラメータ <- *args
任意の数の引数をタプルで受け取る(引数を渡さなければ空のタプルになる)
位置引数で渡す
〜全品物を1枚のプチプチでパックしてダンボールへ〜
2.可変長キーワード引数を受け取るパラメータ <- *kwargs
任意の数のキーワード=値
という形の引数を辞書型(key value
)で受け取る
(引数を渡さなければ空の辞書になる)
キーワード引数で渡す
〜全品物にポストイットで名前をつけた上、全品物を1枚のプチプチでパックしてダンボールへ〜
04.可変長位置
引数を受けとるパラメータの使い方
引数に*
をつけることで、パラメータが可変長位置引数を受け取るようになる。
つまり、任意の数の引数を受け取る。
関数のパラメータのどこに可変長位置引数を定義するかによって、その関数の使い方が変わってくる。
def myfunction(x, y, *z):
print(f'{x} - {y} - {z}')
myfunction(2, 3, 5, 6, 7) # 2 - 3 - (5, 6, 7)
1つ目、2つ目の引数はそれぞれx
,y
に対応している。
それ以降の引数はz
に対応しており、タプルで格納される。
def myfunction(x, *y, z):
print(f'{x} - {y} - {z}')
myfunction(2, 3, 5, 6, 7) # TypeError: myfunction() missing 1 required keyword-only argument: 'z'
パラメータz
に何の引数も渡されていないため、エラーを吐く。この場合、z
はキーワード専用引数になるので、デフォルト値を設定してあげたり、呼び出す時にキーワード引数として使わなければならない。
def myfunction(x, *y, z=0):
print(f'{x} - {y} - {z}')
myfunction(2, 3, 5, 6, 7) # 2 - (3, 5, 6, 7) - 0
def myfunction(x, *y, z):
print(f'{x} - {y} - {z}')
myfunction(2, 3, 5, 6, 7, z=0) # 2 - (3, 5, 6, 7) - 0
05.可変長キーワード
引数の使い方
引数に**
のつけることで、パラメータが可変長キーワード引数を受け取る。
つまり、任意の数のキーワード=値
を受け取り、キーワードと引数は、それぞれを辞書型のkey
とvalue
に対応する。
関数のパラメータのどこに**
を定義するかによって、その関数の使い方が変わってくる。
def myfunction(param1, param2, **param):
print(f'{param1} | {param2} | {param}')
myfunction(2, 3, param3=4, param4=5, param5=6) # 2 | 3 | {'param3': 4, 'param4': 5, 'param5': 6}
可変長キーワード引数で得た値は辞書型になる。
def myfunction(param1, **param, param2):
print(f'{param1} | {param2} | {param}')
結果はシンタックスエラー
可変長キーワード引数を途中に定義することは許できない。
06.2つの可変長引数を併用する場合
可変長位置引数を受け取るパラメータの後においた通常のパラメータは、キーワード専用引数になる。
def Test(a, *b, c): # cはキーワード専用
pass
可変長キーワード引数を受け取るパラメータの後に、通常のパラメータはおけない。
def myfunction(param1, **param, param2):
print(f'{param1} | {param2} | {param}')
よって併用する場合は、以下のような順番にしなければならない。
1.位置引数とキーワード引数の両者を受け取るパラメータ
2.可変長位置引数を受け取るパラメータ
3.キーワード専用引数を受け取るパラメータ
4.可変長キーワード引数を受け取るパラメータ