引数と戻り値:関数とデータのやり取り#

はじめに#

前回の記事では、関数の基本的な概念と定義方法について学びました。今回は、関数をさらに使いこなすために欠かせない「引数」と「戻り値」について詳しく見ていきましょう。

引数と戻り値は、関数が外の世界とやりとりするための重要な手段です。これらを理解することで、もっと柔軟で便利な関数を作れるようになります。

引数とは?#

「引数」(ひきすう)とは、関数に渡すデータのことです。関数を呼び出すときに、括弧の中に書くものが引数です。これによって、同じ処理でも異なるデータに対して適用できるようになります。

例えば、レビューの評価スコアに基づいて星評価(★)を表示する処理を考えてみましょう。評価スコアを受け取って星記号に変換して表示する関数を作ってみます。

>
def display_star_rating(rating):
    """
    評価スコア(10点満点)を星記号に変換して表示する関数

    例:7 → ★★★☆ 
    """
    # ★の数(整数部分)
    full_stars = int(rating / 2)

    # ☆があるか(ratingを2で割ったときに小数部分があるか)
    half_star = (rating % 2) > 0

    # 空欄の数(5から★と☆の数を引く)
    empty_stars = 5 - full_stars - (1 if half_star else 0)

    # 星記号の文字列を作成
    stars = "★" * full_stars
    if half_star:
        stars += "☆"
    stars += " " * empty_stars

    # 結果を表示
    print(f"{stars} ({rating}/10点)")

# 関数を使って異なる評価スコアの商品を表示
product1 = "商品A"
rating1 = 8
print(f"{product1}:", end=" ")
display_star_rating(rating1)

product2 = "商品B"
rating2 = 6
print(f"{product2}:", end=" ")
display_star_rating(rating2)

product3 = "商品C"
rating3 = 9
print(f"{product3}:", end=" ")
display_star_rating(rating3)
商品A: ★★★★  (8/10点)
商品B: ★★★   (6/10点)
商品C: ★★★★☆ (9/10点)

この例では、display_star_rating()関数はratingという引数を一つ受け取り、それを星記号の表示に変換して出力しています。関数の内部では以下のような処理が行われています。

  1. 10点満点の評価を2で割って「★」の数を計算
  2. 2で割った評価の小数部分から「☆」があるかどうか判断
  3. 残りの「空欄」を計算
  4. これらを組み合わせて星記号の文字列を表示

もし関数を使わずに同様の処理を行うと、以下のようにコードが複雑になり、同じ処理を何度も記述する必要があります。

>
# 関数なしの場合
product1 = "商品A"
rating1 = 8
# ★の数(整数部分)
full_stars1 = int(rating1 / 2)
# ☆があるか(ratingを2で割ったときに小数部分があるか)
half_star1 = (rating1 % 2) > 0
# 空欄の数(5から★と☆の数を引く)
empty_stars1 = 5 - full_stars1 - (1 if half_star1 else 0)
# 星記号の文字列を作成
stars1 = "★" * full_stars1
if half_star1:
    stars1 += "☆"
stars1 += " " * empty_stars1
print(f"{product1}: {stars1} ({rating1}/10点)")

# 2つ目の商品も同じ計算を繰り返す必要がある
product2 = "商品B"
rating2 = 6
full_stars2 = int(rating2 / 2)
half_star2 = (rating2 % 2) > 0
empty_stars2 = 5 - full_stars2 - (1 if half_star2 else 0)
stars2 = "★" * full_stars2
if half_star2:
    stars2 += "☆"
stars2 += " " * empty_stars2
print(f"{product2}: {stars2} ({rating2}/10点)")

# 3つ目の商品も同様...(コードが長くなるので省略)

関数を使うと、複雑な処理をひとまとめにして名前を付け、必要なときに再利用できます。例えば、100個の商品に対して星評価を表示する場合でも、関数を使えば同じコードを繰り返し書く必要がなくなります。また、星の表示方法を変更したい場合も、関数内の1箇所を修正するだけで済みます。

複数の引数を使う#

関数は複数の引数を受け取ることもできます。引数はコンマ(,)で区切って指定します。

>
def calculate_rectangle_area(width, height):
    area = width * height
    print(f"幅 {width} cm、高さ {height} cm の長方形の面積は {area} 平方cm です。")

# 関数の呼び出し
calculate_rectangle_area(5, 3)
calculate_rectangle_area(10, 8)
幅 5 cm、高さ 3 cm の長方形の面積は 15 平方cm です。
幅 10 cm、高さ 8 cm の長方形の面積は 80 平方cm です。

この例では、calculate_rectangle_area()関数はwidthheightという2つの引数を受け取ります。これらの値を使って長方形の面積を計算しています。

引数は、定義した順番通りに渡す必要があります。次のようにすると、幅と高さが入れ替わってしまいます。

>
# 引数の順番を入れ替えてみる
calculate_rectangle_area(3, 5)  # 幅3cm、高さ5cmとして計算される
幅 3 cm、高さ 5 cm の長方形の面積は 15 平方cm です。

キーワード引数#

引数を渡すとき、これまでは順番通りに値を指定していました。このように位置で引数を指定する方法を「位置引数」と呼びます。

しかし、引数が多くなると順番を間違えやすくなります。そこで便利なのが「キーワード引数」です。これは、引数の名前を明示的に指定する方法です。

次の例を見てみましょう。

>
def introduce(name, age, hobby):
    print(f"私の名前は{name}です。{age}歳です。趣味は{hobby}です。")

# 位置引数(順番通りに指定)
introduce("山田", 30, "読書")

# キーワード引数(名前を明示的に指定)
introduce(age=25, hobby="映画鑑賞", name="鈴木")
私の名前は山田です。30歳です。趣味は読書です。
私の名前は鈴木です。25歳です。趣味は映画鑑賞です。

キーワード引数を使うと、引数の順番を自由に入れ替えられるので、覚えやすく、間違いも減ります。特に引数が多い関数では、この方法が便利です。

また、位置引数とキーワード引数を組み合わせて使うこともできます。ただし、その場合は必ず位置引数を先に、その後にキーワード引数を書く必要があります。位置引数がキーワード引数の後にある場合は、Pythonのルールに反しているためエラーになります。

>
# 位置引数とキーワード引数の組み合わせ
print("組み合わせの例:")
display_user_info("鈴木", age=42, city="名古屋")  # OK

# 以下はエラーになる例
# display_user_info(name="山田", 25, "京都")  # エラー: 位置引数がキーワード引数の後にある

戻り値とは?#

「戻り値」とは、関数が計算や処理をした結果として返す値のことです。return文を使って値を返すことで、関数の結果を変数に代入したり、別の計算で使ったりできるようになります。

>
def calculate_circle_area(radius):
    area = 3.14 * radius * radius
    return area

# 関数の戻り値を変数に代入
circle1_area = calculate_circle_area(5)
circle2_area = calculate_circle_area(10)

print(f"半径5cmの円の面積: {circle1_area} 平方cm")
print(f"半径10cmの円の面積: {circle2_area} 平方cm")
print(f"二つの円の面積の合計: {circle1_area + circle2_area} 平方cm")
半径5cmの円の面積: 78.5 平方cm
半径10cmの円の面積: 314.0 平方cm
二つの円の面積の合計: 392.5 平方cm

この例では、calculate_circle_area()関数は円の面積を計算し、その結果をreturn文で返しています。関数の呼び出し結果をcircle1_areacircle2_areaという変数に代入し、さらにそれらを使って合計面積を計算しています。

戻り値がない関数とある関数の違いを理解することは重要です。

  • 戻り値がない関数は、主に「何かの動作を実行する」ことを目的とします(例:メッセージの表示)
  • 戻り値がある関数は、「計算結果や処理結果を返す」ことを目的とします(例:面積の計算)

複数の戻り値を返す#

Pythonでは、複数の値を一度にタプルとして返すこともできます。戻り値を複数の変数に直接代入できるので便利です。

>
def calculate_rectangle_properties(width, height):
    area = width * height
    perimeter = 2 * (width + height)
    return area, perimeter

# 複数の戻り値を受け取る
rect_area, rect_perimeter = calculate_rectangle_properties(5, 3)

print(f"面積: {rect_area} 平方cm")
print(f"周囲の長さ: {rect_perimeter} cm")
面積: 15 平方cm
周囲の長さ: 16 cm

この例では、calculate_rectangle_properties()関数は長方形の面積と周囲の長さを計算し、両方を戻り値として返しています。関数の呼び出し結果を2つの変数rect_arearect_perimeterに同時に代入しています。

returnの効果:関数の終了#

return文には、値を返すだけでなく「関数を終了させる」という効果もあります。つまり、関数内でreturnが実行されると、その時点で関数の実行が終わり、残りの処理はスキップされます。

>
def check_score(score):
    if score < 0:
        print("スコアは0以上にしてください。")
        return  # 関数を終了

    if score >= 100:
        print("パーフェクトスコアです!")
    else:
        print(f"あなたのスコアは{score}点です。")

# 関数の呼び出し
check_score(-10)
check_score(80)
check_score(100)
スコアは0以上にしてください。
あなたのスコアは80点です。
パーフェクトスコアです!

この例では、スコアが負の値の場合にエラーメッセージを表示してreturnで関数を終了しています。これにより、不適切な値が渡された場合に残りの処理を実行せず、早めに関数から抜けることができます。この技法は「早期リターン」と呼ばれ、コードをすっきりさせるのに役立ちます。

まとめ#

この記事では、Pythonの関数におけるデータのやり取りの仕組み、「引数」と「戻り値」について学びました。

  • 引数は関数に渡すデータで、関数の動作をカスタマイズできる
  • 引数は位置で指定する方法と、キーワードで指定する方法がある
  • 戻り値は関数が処理した結果を返すもので、return文で指定する
  • 複数の戻り値を一度に返すこともできる
  • return文は関数を終了させる効果もある

次回の記事では、「デフォルト引数」という概念について詳しく学び、より柔軟な関数の定義方法を探っていきます。