今回は特殊な引数の解説の最後として任意引数について説明します。
任意引数とは
任意引数とは関数側で定義することで渡す引数の数に制限なくデータを引き渡すことができます。具体的な話を交えますと関数側で任意引数を一個定義したとします。その関数に対して呼び出し側でデータを渡す際に一個だけでなく3個でも4個でも何個でもデータを渡すことができます。

任意引数の書き方
それでは任意引数の書き方について確認します。任意引数には位置引数とキーワード引数、それぞれにあるので一個ずつ確認します。
位置引数の任意引数
位置引数の任意引数は”*(アスタリスク)”1個を位置引数の前に付けることで定義できます。
def 関数名(*任意位置引数) :
処理を記載
上記を用いれば例えば、関数名(1 , 3 , 5) だったり、 関数名( “word” , “text” ) だったり任意の個数で呼び出すことができます。どの関数でも性質上一個しか定義できないので引数名は “*args” とされることが多いです。なお渡されたデータはタプル型のデータとしてわたります。タプル型のデータは要は値を変更できないリストの事で、 “( )”括弧で囲まれたデータとなっております。(リストは”[]”大括弧です)
1 2 3 4 5 |
def func(*args): print(posarg) func( 2 , 3 , 5) #( 2 , 3 , 5)を出力 |
キーワード引数の任意引数
キーワード引数の任意引数は”**(アスタリスク)”2個をキーワード引数の前に付けることで定義できます。
def 関数名(**任意キーワード引数) :
処理を記載
上記を用いれば、例えば関数名(num = 1 , num2 = 2) だったり、 関数名( animal1 = “cat” , animal2 = “dog” , animal3 = “monky” ) だったり任意の個数でキーワード引数を渡すことができます。
ここで、気になるのが関数で定義した引数名と呼び出し側で使用する引数名の関連性についてですが、呼び出す際に記載する引数名と定義する引数名は一致している必要はありません。なので関数で「**hogehoge」と定義して呼び出し側で「num1 = 1 , num2 = 2」としても「hogehoge」にデータが渡ります。どの引数名でキーワード引数の任意引数を定義しても呼び出し側に影響しないので、一般的に引数名は “**kwargs” と定義されることが多いです。

なお渡されたデータは辞書型のデータとしてわたります。辞書型のデータは後の項で詳しく説明しますが、要は値を特定するためのキーワードと、それに対する値がセットになって格納されたデータの事です。”{}”中括弧を用いて定義します。
{ “東の名探偵” : “工藤新一” ,
“西の名探偵” : “服部平次” }
そのため、キーワード引数として記載した引数名が辞書のキーワードに、キーワード引数に指定した値が辞書の値になりキーワード引数の任意引数にわたります。
1 2 3 4 5 6 |
def func(**kwargs): print(kwargs) #{'eastDetective': '工藤新一', 'westDetective': '服部平次'}を出力 func(eastDetective = "工藤新一" , westDetective = "服部平次") |
引数の優先順位(順番)
任意引数にも優先順位がありますので今までの引数を踏まえて確認します。
まず普通の位置引数とキーワード引数についてです。関数側での意識は通常は必要ありませんが、マーカーを使うと以下のようになるのでした。
★ “/(スラッシュ)” の前は位置引数、
★ “/(スラッシュ)” と “*(アスタリスク)” の間はキーワード引数もしくは位置引数
★ “*(アスタリスク)”の後ろはキーワード引数
つまり、先に、位置引数を定義してキーワード引数が後になります。なので優先順位は
位置引数 > キーワード引数
となります。任意引数についても同じ優先順位になります。
位置引数(任意引数) > キーワード引数(任意引数)
そのため、考えるべきは普通の引数と任意引数についてですが、任意に指定できるものは後になります。そのため、優先順位は
普通の引数 > 任意引数
となります。よって全部合わせると優先順位は以下になります。
位置引数 > キーワード引数 > 位置引数(任意引数) > キーワード引数(任意引数)
ついでににデフォルト引数についても考えてみます。まず、デフォルト引数は通常の引数よりは後ろに書かなくてはいけないのでした。任意引数との優先順位ですが、位置引数の任意引数同じ優先順位です。つまり、位置引数の任意引数とは前でも後ろでもどちらに記載しても問題がなく、キーワード引数よりは先に定義しなくてはなりません。すべての引数の優先順位は最終的に以下のようになります。
位置引数 > キーワード引数 > 位置引数(任意引数) , デフォルト引数 > キーワード引数(任意引数)
任意引数を使用した例
それでは最後に、例を確認します。ここではどういう風に引数が渡されるかを確認したいので関数は引数を出力する簡素なものにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
def func(num1 , num2 , num3 = 1 , *args , **kwargs): print("■■■■■位置引数■■■■■■") print("num1 = " + str(num1)) print("num2 = " + str(num2)) print("■■■■■■■■■■■■■■■") print("■■■■■任意位置引数■■■■") print("*args = " + str(args)) print("■■■■■■■■■■■■■■■") print("■■■■デフォルト引数■■■■") print("num3 = " + str(num3)) print("■■■■■■■■■■■■■■■") print("■■■任意キーワード引数■■■") print("kwargs = " + str(kwargs)) print("■■■■■■■■■■■■■■■") fruite = ["apple" , "banana" , "orange"] func(1,2,10,"word","text",fruite,animal = "cat" , human = "Tomy" , flower = "rose") |
それぞれどういう風に出力されるかGoogleColabで確認してみてください。
任意引数は引数の個数を決めずに処理を実行できたりしてかなり便利ですので扱えるようにしておきましょう。
今回はここまでです。
お疲れ様でした。
コメント