これまでの章で、あなたはデータを整理し(コンテナ)、状況を判断し(条件分岐)、作業を繰り返す(繰り返し)方法を学びました。これらを組み合わせれば、かなり複雑なプログラムも作れるようになってきたはずです。しかし、プログラムが長くなってくると、新たな問題に直面しませんか?「あれ、この計算処理、さっきも書いたような…」「コードが長すぎて、どこで何をしているのか分かりにくい!」といった問題です。
今回は、そんな悩みを一気に解決する魔法のテクニック、「関数」について学んでいきます。関数をマスターすれば、あなたのコードは驚くほど整理され、再利用しやすくなり、プログラミングの効率が飛躍的に向上しますよ!
同じコードを何度も書くのはもうやめよう!
プログラムを書いていると、同じような処理のまとまりを、あちこちで繰り返し使いたい場面がよく出てきます。例えば、「税抜価格から税込価格を計算する」という処理を考えてみましょう。
# 商品Aの税込価格を計算
price_a = 800
tax_rate = 0.1
total_a = price_a * (1 + tax_rate)
print(total_a)
# 商品Bの税込価格を計算
price_b = 1200
total_b = price_b * (1 + tax_rate)
print(total_b)
このコードでは、税込価格を計算する 価格 * (1 + 税率)
というロジックが2回登場しています。今回は2回だけですが、もし100回必要になったら?もし、将来的に税率の計算方法が少し複雑になったら?その100箇所すべてを、間違いなく修正する自信はありますか?
とても大変ですよね。こんな時にこそ「関数」の出番です!
関数とは、一連の処理を一つの「部品」としてまとめて、名前をつけたものです。一度この部品を作ってしまえば、あとはその名前を呼ぶだけで、いつでもどこでも同じ処理を呼び出すことができます。
料理の「レシピ」をイメージすると分かりやすいかもしれません。一度「カレーの作り方」というレシピを完成させてしまえば、あとは「このレシピでカレー作って!」とお願いするだけで、誰でも同じカレーが作れますよね。関数は、まさにプログラムにおけるレシピなのです。
関数の心臓部、「引数」と「戻り値」
では、実際に先ほどの税込価格を計算する関数を作ってみましょう。関数の定義は def
というキーワードを使います。
# 税込価格を計算する関数を定義する
def calculate_tax_included_price(price):
tax_rate = 0.1
total = price * (1 + tax_rate)
return total
# 関数を使って計算する
total_a = calculate_tax_included_price(800)
total_b = calculate_tax_included_price(1200)
print(total_a)
print(total_b)
見事にコードがスッキリしましたね! def
で始まる部分が関数の「定義」、つまりレシピ本体です。そして、calculate_tax_included_price(800)
のように実際に使うことを「呼び出し」と言います。
ここで、二つの非常に重要な専門用語が登場します。「引数(ひきすう)」と「戻り値(もどりち)」です。
引数 (Argument):関数に渡す材料
関数を定義する時、def calculate_tax_included_price(price):
のカッコの中に price
という変数がありますね。これは、この関数が仕事をするために外部から受け取る「材料」です。これを仮引数(かりひきすう)と呼びます。
そして、関数を呼び出す時に calculate_tax_included_price(800)
のように渡している 800
という具体的な値。これが引数です。
800
という引数が、関数の中では price
という仮引数に入り、計算に使われるわけです。これにより、800
の計算も 1200
の計算も、同じ関数を使い回して実行できるのです。引数は、関数を柔軟で再利用可能な部品にするための、鍵となる仕組みです。
戻り値 (Return Value):関数からの成果物
関数の中で計算した結果を、関数の呼び出し元に返してあげる必要があります。その役割を果たすのが return
です。return total
と書くことで、「total
変数の中身を、この関数の成果物として返します!」と宣言しているのです。
呼び出し元の total_a = calculate_tax_included_price(800)
というコードは、「calculate_tax_included_price
関数を 800
という材料で動かして、返ってきた成果物を total_a
という変数にしまいなさい」という意味になります。
この「引数」と「戻り値」のデータの受け渡しがあるおかげで、関数は独立した部品として機能することができるのです。
応用テクニック:一度に複数の値を返す
関数は、実は一度に複数の値を返すこともできます。例えば、ある数値リストを受け取って、その合計値と平均値の両方を計算して返したい、なんて時に便利です。
def calculate_sum_and_average(numbers):
total = sum(numbers) # sum()はリストの合計を計算する組み込み関数
average = total / len(numbers) # len()はリストの要素数を数える組み込み関数
return total, average
scores = [88, 92, 75, 80, 95]
s, a = calculate_sum_and_average(scores)
print("合計点:", s)
print("平均点:", a)
return total, average
のように、返したい値をカンマで区切って並べるだけです。簡単でしょう?
呼び出し側では s, a = ...
のように、受け取るための変数をカンマで区切って用意します。すると、return
された値が順番にそれぞれの変数に代入されます。
これは、Pythonが内部で自動的に(total, average)
という「タプル」を作って返し、それを受け取り側で分解(アンパック)している、という仕組みになっています。複数の計算結果をスマートに扱えると、コードの幅がさらに広がりますよ。
関数の独立性を壊す危険なワナ
最後に関数を使う上での、とても重要な注意点をお話しします。それは「グローバル変数」の扱いです。
関数の外側で定義された変数をグローバル変数と呼びます。そして、関数の中から、このグローバル変数を読み書きすることができてしまいます。
# グローバル変数
tax_rate = 0.1
def calculate_bad_example(price):
# 関数の外にある tax_rate を直接使ってしまっている!
total = price * (1 + tax_rate)
return total
print(calculate_bad_example(1000))
一見、このコードは問題なく動きます。しかし、これは非常に危険な書き方です。なぜなら、この関数の計算結果が、関数の外側にある tax_rate
という変数の状態に完全に依存してしまっているからです。
もし、プログラムのどこか別の場所で、誰かがうっかり tax_rate = 0.08
と書き換えてしまったら?この関数の計算結果は、意図せず変わってしまいます。関数が独立した「部品」ではなくなり、外部の環境に左右される、不安定で予測不能な存在になってしまうのです。
良い関数とは、外部とのやり取りを引数と戻り値だけで完結させている、独立性の高い部品です。これを意識して設計することが、バグが少なく、メンテナンスしやすいプログラムを作るための秘訣です!
まとめ:プログラムを「設計」する第一歩
お疲れ様でした!今回は、コードを部品化し、再利用可能にするための強力なツール「関数」を学びました。
- 関数: 処理をひとまとめにし、名前をつけた部品。
def
で定義する。 - メリット: コードの再利用性が高まり、見通しが良くなり、修正も楽になる。
- 引数: 関数に渡す「材料」となるデータ。
- 戻り値: 関数が返す「成果物」となるデータ。
return
で指定する。 - 独立性: 良い関数は、引数と戻り値だけで外部とやり取りし、グローバル変数に依存しない。
関数を使いこなすことは、単にコードを書くことから、プログラム全体を「設計」することへのステップアップを意味します。
さて、私たちは自作の「処理(動詞)」を作れるようになりました。でも、プログラムの世界には「データ(名詞)」と「処理(動詞)」をひとまとめにした、もっと強力な部品の作り方があります。それが次の章で学ぶ「オブジェクト」です。プログラミングの考え方が、また一段と深まりますよ。どうぞ、お楽しみに!
まとめができたら、アウトプットとして演習問題にチャレンジしましょう。