Python超入門⑤ 関数で処理をまとめよう
def、引数、戻り値、デフォルト引数、変数のスコープを学び、処理を読みやすく分けます。
似た処理を何度もコピーしていると、「1か所直したのに、もう1か所は直し忘れた!」ということが起きます。
そんなときに役立つのが関数です。処理に名前を付けてまとめ、必要なところから呼び出せるようにします。今回は、あいさつを表示する小さな関数から始めて、計算結果を返す関数へ進みましょう。
今回分かるようにしたいこと
defで関数を作り、呼び出す- 引数で値を渡す
returnで結果を返す- 表示することと、結果を返すことを区別する
この記事はPython 3用です。各コード欄は、別々の例として実行してください。変数とif文を使います。関数の説明の中にも新しい言葉が出るので、1つずつ確認していきます。
1. 関数を「作る」と「使う」は別の操作
まずは3行の例
def greet():
print("こんにちは")
greet()
こんにちは
def は「関数を定義する」、つまり処理に名前を付けて用意するためのキーワードです。greet が付けた名前で、greet() と書くと使えます。この「使う」操作を呼び出しといいます。
| 部分 | 役割 |
|---|---|
def |
関数を用意する |
greet |
関数の名前 |
() |
今回は渡す値がないため空 |
: |
関数の処理がここから続くことを示す |
| 字下げした行 | 呼び出されたときに動く処理 |
最後の greet() |
用意した関数を呼び出す |
定義しただけでは、あいさつは出ない
最後の greet() を消すと、何も表示されません。関数を用意することと、中の処理を実行することは別だからです。
実行の順番は、こうなります。
defの行で、greetという関数を用意する- 字下げされた中身は、まだ実行しない
- 下の
greet()で関数を呼ぶ - 関数の中へ進み、「こんにちは」を表示する
- 関数を呼んだ場所へ戻る
ここがつかめると、コードを上から読んだときに「なぜ途中の行を飛ばすの?」という疑問も減ってきます。関数定義の公式説明でも、この定義と実行の違いを確認できます。
2. 引数で「今回使う値」を渡す
名前だけ変えて、同じ処理を使う
def greet(name):
print(f"こんにちは、{name}さん")
greet("Aoi")
greet("Ren")
こんにちは、Aoiさん
こんにちは、Renさん
greet("Aoi") の "Aoi" は、関数へ渡す引数(ひきすう)です。関数側の name が、その値を受け取るための名前になります。
厳密には、定義側の name を仮引数、呼び出し側の "Aoi" を実引数と区別します。ただ、最初は「受け取る名前」と「渡す値」を見分けられれば十分です。
1回目と2回目を分けて考える
| 呼び出し | その回のname | 表示 |
|---|---|---|
greet("Aoi") |
"Aoi" |
こんにちは、Aoiさん |
greet("Ren") |
"Ren" |
こんにちは、Renさん |
あいさつの文章を変えたければ、関数の中を1か所直せば済みます。「同じ処理を何度も書かなくていい」という便利さは、ここにあります。
ただし、greet(name) と定義しているのに greet() と値を渡さず呼ぶと、必要な引数がないため TypeError になります。引数の数が合っているかも確認しましょう。
3. returnは、結果を呼び出し元へ返す
計算した結果を、後でも使いたい
次は、商品の小計を計算する関数です。
def subtotal(price, count):
return price * count
amount = subtotal(160, 3)
print(amount)
print(amount + 100)
480
580
戻り値(もどりち)は、関数から返される結果です。return の後ろに書いた値が、関数を呼んだ場所へ戻ります。
動きを分けてみましょう。
subtotal(160, 3)を呼び出す- 関数の中では
priceが160、countが3になる price * countを計算し、480を得るreturnが480を返すamount = subtotal(160, 3)の呼び出し結果が480になり、amountに代入される
次の行では、その結果をさらに計算できます。関数は「画面に出すだけのもの」ではないんですね。
printとreturnを混ぜない
def show_subtotal(price, count):
print(price * count)
result = show_subtotal(160, 3)
print(result)
480
None
「480を出しているのに、なぜNone?」と感じるかもしれません。
print() は画面へ表示する操作です。それだけでは、関数の戻り値を480にできません。return で値を返さずに関数の最後まで進むと、Noneという「ここでは返す値を用意していない」ことを表す値が返ります。
| 書き方 | 画面へ表示 | 後の計算に結果を渡す |
|---|---|---|
print(price * count) |
する | この行だけではできない |
return price * count |
しない | できる |
計算する関数は計算結果を返し、呼び出した側で表示する。この分け方にすると、画面表示以外にも結果を使いやすくなります。returnの正式な動作も参考になります。
4. returnに到達したら、その関数は終わる
def shipping_fee(total):
if total >= 3000:
return 0
return 300
print(shipping_fee(3200))
print(shipping_fee(1800))
0
300
これは「3000円以上なら送料0円、それ以外は300円」という練習用に決めたルールです。特定のお店の料金ではありません。
3200の場合、最初の return 0 で関数が終わるため、後ろの return 300 は実行されません。1800ならif文の中に入らず、最後の行で300が返ります。
return は「ここまでの結果を返して、この関数を終える」と読むと分かりやすいです。プログラム全体を終了するわけではなく、呼び出し元へ戻ります。
5. 省略したときの値を決める:デフォルト引数
def greet(name, message="こんにちは"):
return f"{message}、{name}さん"
print(greet("Aoi"))
print(greet("Ren", "おはよう"))
print(greet("Mio"))
こんにちは、Aoiさん
おはよう、Renさん
こんにちは、Mioさん
message="こんにちは" は、messageを省略したときに使うデフォルト値です。
2回目では "おはよう" を渡していますが、これはその呼び出しで使う値を指定しただけ。デフォルト値そのものを書き換えたわけではないので、3回目は「こんにちは」に戻ります。
公式には、デフォルト値は関数を定義するときに評価されます。そのため、変更できるリストなどをデフォルト値にすると、意図せず呼び出し間で共有されることがあります。まずは、この例のような文字列や数値で使い方を覚えましょう。デフォルト引数の注意点
6. スコープ:その名前をどこから使える?
スコープは、変数などの名前が使える範囲のことです。関数の中で代入した名前は、基本的にその関数の中で使うローカル変数になります。
def make_message():
message = "準備できました"
return message
text = make_message()
print(text)
準備できました
関数の外から message を直接使おうとすると、この例では NameError になります。でも、値を return で返して、外側の text で受け取ることはできます。
名前の使える範囲と、値を渡せるかどうかは別の話です。「中の変数を無理に外へ見せる」のではなく、必要なものを引数で渡し、結果を戻り値で受け取ると、処理のつながりが読みやすくなります。
7. 練習:大きい方を返す関数を作ろう
2つの数を受け取り、大きい方を返す larger 関数を作ってください。数が同じ場合は、その数を返します。
確認用の例は3つです。
larger(12, 7)→ 12larger(4, 9)→ 9larger(5, 5)→ 5
模範解答
def larger(a, b):
if a >= b:
return a
return b
print(larger(12, 7))
print(larger(4, 9))
print(larger(5, 5))
12
9
5
解説:どのreturnを通る?
a >= b は「aがb以上か」という条件です。
| aとb | 条件 | 返す値 |
|---|---|---|
| 12と7 | True | 最初のreturnで12 |
| 4と9 | False | 最後のreturnで9 |
| 5と5 | True | 最初のreturnで5 |
最初の return が実行されたら関数は終わるので、この例では else がなくても動きます。もちろん、else を使って書いても構いません。
同じ値の場合まで試すのは、境界の確認のためです。「普段の入力では動くけれど、同じ数のときだけ違う」といったミスを見つけやすくなります。
まとめ:値の行き来が見えれば大丈夫
関数の最初の山場は、def の書き方よりも「いつ実行され、どこへ戻るか」です。
呼び出し → 引数を受け取る → 処理する → returnで返す → 呼び出した場所へ戻る。
この順番を追えれば、長いプログラムも小さな仕事に分けて読めるようになります。最初から何でも関数にする必要はありません。同じ処理が繰り返されたときや、ひとまとまりに名前を付けたくなったときに使ってみましょう。
前の記事:Python超入門④ 繰り返し
次の記事:Python超入門⑥ リストと辞書