関数、引数、戻り値の基礎

関数の目的

後から発生する手間(面倒)を、できるだけ小さくすること。

  • 何度も同じ処理、似たような処理を書かないようにする。
    もし変更が必要になった場合、処理をまとめた関数を作っておけば、その関数だけ変更すればいいので楽である。

  • 可読性をよくする。
    長いコードは読みにくい。読みにくいコードは間違いのもとである。
    ひとつの関数で40行を超えてきたあたりから、関数の分割を検討しよう。

関数の定義方法

引数なし、戻り値なし

とりあえず処理をまとめておく時に使う。
省略しているだけで、引数、戻り値が存在しないわけではない。

def no_arguments_no_return():
    a = 10
    b = 20
    c = a + b
    print("a={}, b={}, c={}".format(a, b, c))

実行方法(関数の呼び出し)

no_arguments_no_return()

実行結果

a=10, b=20, c=30

引数あり、戻り値あり

  • 引数:関数内の変数に渡す値のこと。

  • 戻り値:その関数を実行すると生成される値のこと。

次の関数で説明すると、a, b を引数、c を戻り値という。

def with_arguments_with_return(a, b):
    c = a + b
    print("a={}, b={}, c={}".format(a, b, c))
    return c

実行方法

a = 30
b = 40
return_value = with_arguments_with_return(a, b)
print("return value:", return_value)

便宜上、a, b を先に定義しているが、次のように直接渡してもかまわない。

return_value = with_arguments_with_return(30, 40)
print("return value:", return_value)

実行結果

a=30, b=40, c=70
return value: 70

ちなみに、return は実行中の関数を抜けるということである。
つまり、return 以降にコードがあっても、そこまで到達しないので実行されることはない。

また、上のサンプルコードでは戻り値が c ひとつだけだが、次のようにカンマで区切れば複数個をタプル型で返せる。
(タプル型は中身を変更できないリストのようなもの)

def multiple_return_values(a, b):
    c = a + b
    print("a={}, b={}, c={}".format(a, b, c))
    return a, b, c

動作確認

a = 30
b = 40
return_value = multiple_return_values(a, b)
print("return value:", return_value, type(return_value))

実行結果

a=30, b=40, c=70
return value: (30, 40, 70) <class 'tuple'>

可変長引数

引数の数が状況によって変化する時に使用する手法。
引数の前に * (アスタリスク)をつけると可変長引数となる。
可変長引数は関数内にタプル型で展開される。

def variable_length_arguments(*args):
    a = args[0]
    b = args[1]
    c = a + b
    print("a={}, b={}, c={}".format(a, b, c))
    return c

動作確認

a = 100
b = 200
return_value = variable_length_arguments(a, b)
print("return value:", return_value)

実行結果

a=100, b=200, c=300
return value: 300

可変長引数には、次のようにリストを渡してもよい。

num_args = [100, 200]
return_value = variable_length_arguments(*num_args)
print("return value:", return_value)

引数にセットしたリストの先頭に*をつけると、中身を展開して渡すという意味になる。
実行結果は変わらないので、状況(コードの読みやすさ)にあわせて使い分けよう。

デフォルト引数

関数に引数が指定されていない時、デフォルトで使用する値を決めておくことができる。
使いどころが難しいが、例えば(こじつけ感がすごいが)次のようなケースに使用できる。

def default_argument(a, b, mode='int'):
    c = a + b
    print("a={}, b={}, c={}".format(a, b, c))
    if mode == 'int':
        return c
    elif mode == 'str':
        return str(c)
    else:
        return None
  • a, b には数字(int型)がセットされる想定である。
  • この関数は a + b の結果である c を返すものであるから、戻り値も数字(int型)である。
  • 大多数の人はこれで十分であるが、戻り値を文字列(str型)で受け取りたいというニーズも僅かに存在する。
  • それに応えるために、引数で戻り値の型を引数modeの値で選択できるように改良した。
  • しかし、大多数の人にとっては、この引数は冗長なものである。
  • そこで、modeのデフォルト引数を'int'に設定し、これを省略可能とする。
  • これにより、従来どおりの使い勝手のまま機能を追加することができる。

動作確認

a = 100
b = 200
return_value = default_argument(a, b)
print("return value:", return_value, type(return_value))
return_value = default_argument(a, b, 'str')
print("return value:", return_value, type(return_value))

実行結果

a=100, b=200, c=300
return value: 300 <class 'int'>
a=100, b=200, c=300
return value: 300 <class 'str'>