12
13

More than 3 years have passed since last update.

【Python】*args **kwrgs って何だろう

Last updated at Posted at 2019-12-19

01.本記事に書くこと

  • 関数のパラメータに定義する***の意味と、その使い方

時間が経ってしまっても素早く思い出せるように、ここに整理したいと思います。

02.***は可変長引数を受け取るパラメータにつけるものである

関数のパラメータに*args**kwargsと書いてあるコードを見かけた。
これは可変長引数を受け取るパラメータに記述されるもので、関数呼び出し時にパラメータに渡す引数の数を、固定ではなく任意の数にできるようになる。

可変長引数とは、通常1つしか引数が指定できないところ、任意数の引数を指定できるようにしたもの。

〜普通はダンボール1つにつき1つの品物しか入れられない。
しかし、可変長引数ならば1つのダンボールにつき、いくらでも品物を入れることができる上に、それらは1枚のプチプチでパックされる。〜

def kansu(*args):
    print(f'{args}を受け取った!')

kansu('Apple', 'Banana', 100) 
# ('Apple', 'Banana', 100)を受け取った!

パラメータはargs1つだけに対して、3つの引数を渡しているが、エラーなく動作している。

身近な例でいうと、print()関数.format()メソッドでも可変長引数が用いられている。

いくらでも引数を渡せる
print('a','b','c') # a b c

又、argskwargsという名前は慣習的に用いられるものなので、好きな名前でも動作する。

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.可変長位置引数を受けとるパラメータの使い方

引数に*をつけることで、パラメータが可変長位置引数を受け取るようになる。
つまり、任意の数の引数を受け取る。
関数のパラメータのどこに可変長位置引数を定義するかによって、その関数の使い方が変わってくる。

1.最後のパラメータが可変長
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に対応しており、タプルで格納される。

2.途中のパラメータが可変長
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はキーワード専用引数になるので、デフォルト値を設定してあげたり、呼び出す時にキーワード引数として使わなければならない。

2-1.デフォルト値を設定
def myfunction(x, *y, z=0):
    print(f'{x} - {y} - {z}')

myfunction(2, 3, 5, 6, 7) # 2 - (3, 5, 6, 7) - 0
2-2.キーワード引数として使う
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.可変長キーワード引数の使い方

引数に**のつけることで、パラメータが可変長キーワード引数を受け取る。
つまり、任意の数のキーワード=値を受け取り、キーワードと引数は、それぞれを辞書型のkeyvalueに対応する。
関数のパラメータのどこに**を定義するかによって、その関数の使い方が変わってくる。

1.最後のパラメータを可変長キーワード引数にする
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}

可変長キーワード引数で得た値は辞書型になる。

2.途中のパラメータを可変長キーワード引数にする
def myfunction(param1, **param, param2):
    print(f'{param1} | {param2} | {param}')

結果はシンタックスエラー
可変長キーワード引数を途中に定義することは許できない。

06.2つの可変長引数を併用する場合

可変長位置引数を受け取るパラメータの後においた通常のパラメータは、キーワード専用引数になる。

def Test(a, *b, c): # cはキーワード専用
  pass

可変長キーワード引数を受け取るパラメータの後に、通常のパラメータはおけない。

05-2.再掲
def myfunction(param1, **param, param2):
    print(f'{param1} | {param2} | {param}')

よって併用する場合は、以下のような順番にしなければならない。

1.位置引数とキーワード引数の両者を受け取るパラメータ
2.可変長位置引数を受け取るパラメータ 
3.キーワード専用引数を受け取るパラメータ
4.可変長キーワード引数を受け取るパラメータ
12
13
0

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
12
13