関数の定義と呼び出し
>>> def sum1(start, end): ... n = 0 ... for i in xrange(start, end+1): n += i ... return n # return文で値を返す ... >>> sum1(1, 10) 55 >>> sum1(start=1, end=10) # "仮引数名=実引数"で引数を渡す(キーワード引数) 55 >>> sum1(end=10, start=1) # 順番を入れ替えてもよい 55 >>> args = (10, 50) >>> sum2(*args) # タプルを展開 sum2(10, 50)と同じ 1230 >>> keys = {"start":10, "end":50} >>> sum2(**keys) # 辞書を展開 sum2(start=10, end=50)と同じ 1230 >>> >>> sum2(start=10, 50) # キーワード引数の後に非キーワード引数を渡すとエラー File "<stdin>", line 1 SyntaxError: non-keyword arg after keyword arg >>> >>> sum2(10, start=10) # startは第一引数で既に渡されているのでエラー Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum2() got multiple values for keyword argument 'start' >>> >>> args = (10, 100, 1000) >>> sum2(*args) # 引数とタプルの要素数が合っていないとエラー Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum2() takes at most 2 arguments (3 given) >>> >>> keywords = {"start":10, "end":50, "step":2} >>> sum2(**keywords) # 関数定義にないキーワード引数を渡すとエラー Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: sum2() got an unexpected keyword argument 'step'
>>> def print_hello(): # 引数がなくても( )は必要 ... print "hello" ... >>> print_hello() # 呼び出す場合も( )は省略不可 hello
>>> def sum2(start=1, end=100): # 引数にデフォルト値を指定 ... n = 0 ... for i in xrange(start, end+1): n += i ... return n ... >>> sum2() # デフォルト値が指定されているので引数を省略できる 5050 >>> sum2(50) # 第二引数だけを省略 3825 >>> sum2(end=50) # キーワード引数を使って第一引数だけを省略 1275
>>> def test(a, b=1, # 固定引数 ... *args, # 可変長の非キーワード引数をタプルで受け取る ... **keywords # 可変長のキーワード引数を辞書で受け取る ... # この場合は第3引数以降の非キーワード引数を*argsで ... # キーワード引数を**keywordsで受け取る ... ): ... print a, b ... print args ... print keywords ... >>> test(0, 1) 0 1 () {} >>> test(0, 1, 2, 3, 4, 5) 0 1 (2, 3, 4, 5) {} >>> test(0, b=1, c=2, d=3) 0 1 () {'c': 2, 'd': 3} >>> test(0, 1, 2, 3, c=4, d=5) 0 1 (2, 3) {'c': 4, 'd': 5}
引数はオブジェクトの参照
引数として渡される値はオブジェクトのコピーではなく参照です。ですから、関数の中で元のオブジェクトの中身を変えることができます。
>>> def sum(list): ... n = 0 ... while list: n += list.pop() ... return n ... >>> list = [1, 2, 3, 4, 5] >>> sum(list) 15 >>> list []
基本的には関数内で引数の中身を変えるようなことはしない方がよいと思います。
引数のデフォルト値は共有
デフォルト値は一度だけ評価され、共有されます。引数を省略した場合に同じオブジェクトを参照するので、同じ引数で関数を呼び出しても、そのたびに戻り値が違ってしまうことがあります。
>>> def test(a, list=[]): ... list.append(a) ... return list ... >>> test(1) [1] >>> test(1) [1, 1] >>> test(1) [1, 1, 1]
引数の指定順序
関数定義で使われる引数を仮引数といいます。仮引数は以下の順序で指定しなければなりません。また、*と**のついた仮引数は一つずつしか指定できません。
def test(str, # 必須の引数 num=1, # デフォルト値のある引数 *args, # 可変長のキーワード引数を受け取るタプル **keywords, # 可変長のキーワード引数を受け取る辞書 ): print a, b, c, d
関数呼び出しで使われる引数は実引数といいます。実引数は以下の順序で渡さなければなりません。また、*と**のついた実引数は一つずつしか渡せません。
test(0, # 非キーワード引数 num=1, # キーワード引数 *args, # リストまたはタプルを展開 **keywords # 辞書を展開 )