Python × 入門 | #15 戻り値とスコープを理解しよう

0-14では、処理を関数にまとめる方法を学びました。今回はその続きとして、関数が計算結果を返す return と、変数が使える範囲である スコープ を整理します。

関数は「まとまった処理」ですが、本当に便利になるのは、結果を外へ返し、その結果を別の計算に使えるようになってからです。ここを理解すると、ただ長いコードを書く段階から、部品を組み合わせて考える段階へ進めます。

戻り値とスコープを理解しよう

まずはPycoBlocksを開こう

下のPycoBlocksで直接作業するか、別タブで開き、生成されるPythonコードを見ながら進めてください。

用語 意味
return 関数の中で作った値を呼び出し元へ返すキーワード return a + b
スコープ(scope) 変数が使える範囲。関数の内と外では別のスコープになる 関数の中の x と外の x は別物
ローカル変数 関数の中で定義された変数。その関数の中だけで使える def f(): の中で作った変数
None 「値がない」ことを表すPythonの特別な値。returnがない関数の戻り値 print(show_name("A"))None

ステップ1:returnは「結果を外へ返す」命令

print() は画面に表示する命令です。一方で return は、関数の中で作った値を、関数を呼び出した場所へ返します。表示するだけなら print() で十分ですが、結果を変数に入れて次の処理に使うなら return が必要です。

a_return_store
def add(a, b):
    return a + b

result = add(3, 5)
print(result)

add(3, 5) の場所には、関数から返ってきた 8 が入ります。その値を result に代入してから表示しているので、計算と表示を分けて考えられます。

ステップ2:関数の中で作った変数は外から見えない

関数の中で作った変数は、その関数の中だけで使えます。この「変数が有効な範囲」をスコープと呼びます。関数の中で total を作っても、関数の外でそのまま total を使えるわけではありません。

b_local_scope
def subtotal(price, count):
    total = price * count
    return total

print(subtotal(120, 3))

この例では、totalsubtotal() の中だけで使う一時的な変数です。外へ出したい値は、return total として明示的に返します。

ステップ3:同じ名前でも内側と外側は別の変数

関数の外にも中にも同じ名前の変数があると、初心者は混乱しやすいです。Pythonでは、関数の中で代入した変数は基本的にローカル変数、つまり関数の中だけの変数として扱われます。

c_same_name_scope
message = "外側"

def make_message():
    message = "関数の中"
    return message

print(make_message())
print(message)

最初の print() では関数の中で作った "関数の中" が表示されます。次の print(message) では、外側の message がそのまま表示されます。同じ名前でも、スコープが違えば別物として考えます。

ステップ4:returnしない関数はNoneを返す

Pythonの関数は、return を書かない場合でも、実は None という特別な値を返します。None は「値がない」ことを表す値です。

returnしない関数はNoneを返す
def say_hello():
    print("Hello!")

result = say_hello()
print(result)

このコードでは、まず関数の中の Hello! が表示されます。その後、say_hello() の戻り値を入れた result を表示すると None が出ます。「表示する関数」と「値を返す関数」は、目的が違うと考えると整理しやすいです。

コーディングモードで書いてみよう

少し発展すると、関数は「入力を受け取り、結果を返す」形にしておくと扱いやすくなります。画面表示や入力を関数の中に混ぜすぎると、あとでテストしにくくなります。

def judge_pass(score):
    return score >= 60

score = 75
if judge_pass(score):
    print("合格")
else:
    print("再挑戦")

judge_pass() は表示をせず、真偽値だけを返します。このようにしておくと、judge_pass(59)judge_pass(60) を試すだけで、判定ロジックが正しいか確認できます。

演習課題

課題15-1:二乗を返す関数を作ろう

数値 n を受け取り、n * nreturn する square(n) 関数を作ってください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

ans1_square
def square(n):
    return n * n

print(square(6))

解説: return により、計算結果が square(6) の場所へ返ります。返ってきた値を print() で表示しています。

課題15-2:合計金額を返そう

単価 price と個数 count を受け取り、合計金額を返す total_price(price, count) 関数を作ってください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

ans2_total_price
def total_price(price, count):
    total = price * count
    return total

print(total_price(120, 3))

解説: total は関数の中だけで使うローカル変数です。外で使いたい値は return total で返します。

課題15-3:Noneが出る理由を説明しよう

return がない関数の戻り値を変数に入れて表示すると、None が出る例を作ってください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

模範解答:Noneが出る例
def show_name(name):
    print(name)

result = show_name("Aoi")
print(result)

解説: show_name() は表示はしますが、値を返していません。そのため戻り値は None になります。

課題15-4:3つの数の最大値を返そう

3つの数 a, b, c を受け取り、最も大きい値を返す max3(a, b, c) 関数を作ってください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

模範解答:3つの数の最大値
def max3(a, b, c):
    biggest = a
    if b > biggest:
        biggest = b
    if c > biggest:
        biggest = c
    return biggest

print(max3(12, 5, 20))

解説: 0-7の if と組み合わせています。biggest は関数の中だけで使う変数なので、外側の他の変数と混ざりません。

課題15-5:割引後の価格を返そう

価格 price と割引率(パーセント) percent を受け取り、割引後の価格を整数で返す discounted(price, percent) 関数を作ってください。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

模範解答:割引後の価格
def discounted(price, percent):
    return price * (100 - percent) // 100

print(discounted(2000, 15))

解説: percent15 を渡すと15%引きです。price × (100 - percent) // 100int(price × (1 - percent/100)) と同じ整数の割引後価格を、整数だけの計算で求める書き方です。計算結果を返す関数にしておくと、別の商品価格にも同じ処理を使えます。

まとめ

  • return は、関数の中で作った値を呼び出し元へ返します
  • print() は表示、return は値を返す命令です。目的が違います
  • 関数の中で作った変数は、基本的に関数の中だけで使えるローカル変数です
  • 同じ名前の変数でも、スコープが違えば別の変数として考えます
  • return がない関数は None を返します

次は、データと処理をひとまとめにする「クラス」を学びます。→ Python × 入門 | #16 クラスを使ってみよう

PAGE TOP