###可変長引数
可変長引数は、その名の通り引数の長さを自由に変えられる引数。
なので、どんな数の引数を渡しても対応できる関数となるわけです。
関数の引数に*
または**
をつけると定義できます。
可変長引数は各々ひとつづつしか定義できません。
※ややこしかったので、うまくまとまってないかもしれないです。
まず、簡単なサンプルから
$ python3
Python 3.5.0 ()
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def print_parameters(*arguments, **keyword_arguments):
... print('args =', arguments)
... print('kwargs =', keyword_arguments)
...
>>> print_parameters(1,2,3,4, a=4, b=3, c='hoge')
args = (1, 2, 3, 4)
kwargs = {'c': 'hoge', 'b': 3, 'a': 4}
簡単な使い方としてはこんな感じです。
(*argsはarguments, kwargsはkeyword argumentsのことです)
*arguments
のように*
を付けると普通の引数をtuple
にしてまとめてくれます。
**keyword_arguments
のように**
をつけるとkeyword引数をdict
にまとめてくれます。当然ながら、=
の左側には半角数字で始まるものは書けません。
###普通の引数を混ぜる
絶対に引数として受け取るものがある場合。
*
がついてる引数の前後に置くことができます。
keyword引数は引数の最後に書く決まりがあるので、**
の後ろには何も引数を書くことができません。
この際の注意点としては、*
がついてる引数の前に置いた引数をkeyword引数として書けない。
*
の後ろに置いた引数はkeyword引数として書かなければいけないことです。
>>> def print_parameters(flag, *arguments, length, **keyword_arguments):
... print(flag, length)
... print('args =', arguments)
... print('kwargs ='keyword_arguments)
>>> print_parameters(True,1,2,3,4,length=4, args=4, a=3, c='hoge')
True 4
(1, 2, 3, 4)
{'args': 4, 'c': 'hoge', 'a': 3}
>>> print_parameters(True, length=0)
True 0
args = ()
kwargs - {}
エラー例:flagをkeyword引数とした場合
>>> print_parameters(1, 2, 3, 4,flag=False, length=4, args=4, a=3, c='hoge')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print_parameters() got multiple values for argument 'flag'
エラー例:lengthをkeyword引数で書かなかった場合
>>> print_parameters(True,1,2,3,4,4, args=4, a=3, c='hoge')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: print_parameters() missing 1 required keyword-only argument: 'length'
このように、エラーを吐き出してきます。
おそらく、引数は手前から処理するので、flag
の場合は先に1
が代入されているのにkeyword引数でflag=False
とまたflag
をいじろうとしたのでエラーが出た。
length
の場合*arguments
が1,2,3,4,4
をすべて受け取ってしまうためlength
に入るものがなくなってしまったという感じだと思います。
この際、length
に関数を定義する際にデフォルト値を設定すればエラーは起こりません。
###list(tuple)やdictの中身を引数として渡すには
ここからは、可変長引数を使っていますが、あまり可変長引数とは関係なく、基礎の話です。
普通に渡すと、
>>> def print_parameters(flag, *arguments, length, **keyword_arguments):
... print(flag, length)
... print('args =', arguments)
... print('kwargs =`, keyword_arguments)
>>> print_parameters(True, [1,2,3,4,5], {'a':5, 'b':2} , length=2)
True 2
args = ([1, 2, 3, 4, 5], {'b': 2, 'a': 5})
kwargs = {}
list, dictそれぞれ一つの変数として*argument
に入ります。
list(tuple)
を各要素を引数として渡したい場合は
>>> print_parameters(*[True, 1,2,3,4,5], 6, length=6)
True 6
args = (1, 2, 3, 4, 5, 6)
kwargs = {}
このように、*
をlist
の前につけることでひとつひとつ渡すことができます。
次に、dict
をkeyword引数として渡したい場合は
>>> print_parameters(**{'flag':True, 'length':5, 'a':0, 'b':1}, c=1, d=3)
True 5
args = ()
kwargs = {'c': 1, 'd': 3, 'b': 1, 'a': 0}
dict
の場合は**
をつけることでkeyword引数に混ぜることができます。
もともと関数で定義されているkeyword(flagとlength)はそっちにに代入され、それ以外はkeyword_arguments
に入ります。
dict
は*
をひとつだけつけた場合には、keyをすべて渡してくれます。
>>> dic = {'flag':True, 'length':0, 'a':1, 'b':2}
>>> print_parameters(True, *dic, length=4)
True 4
args = ('flag', 'b', 'a', 'length')
kwargs = {}
こんな感じになります。
###まとめ
今回、可変長引数について書きました。
**
はkeyword引数をdictにまとめてくれる。(定義されているkeyword引数は別)
*
は引数をtupleにまとめてくれる。
keyword引数は一番右にまとめて書く。
可変長引数、keyword可変長引数はひとつの関数に各々ひとつしか書けない。