関数の基本
これまでのコードは 1 行ずつ実行されてきました。しかし、同じ機能を再利用する必要がある場合はどうすればよいでしょうか?毎回コピー&ペーストしますか?関数がこの問題を解決します——コードのブロックをパッケージ化し、名前を付けて、必要なときにいつでも呼び出します。これは「コードを書く」から「コードを整理する」への第一歩です。
1. 関数とは
関数は名前付きのコードブロックで、いつでも呼び出すことができます。
# 関数を定義
def say_hello():
print("Hello!")
print("Welcome to Python!")
# 関数を呼び出し
say_hello()
say_hello() # 複数回呼び出せる
出力:
Hello!
Welcome to Python!
Hello!
Welcome to Python!
2. パラメータ:関数にデータを渡す
関数はパラメータを受け取ることで、より柔軟になります:
def greet(name):
"""名前で挨拶する"""
print(f"Hello, {name}! Welcome to Python.")
greet("Zhang San") # Hello, Zhang San! Welcome to Python.
greet("Li Si") # Hello, Li Si! Welcome to Python.
複数パラメータ
def introduce(name, age, city):
print(f"My name is {name}, I'm {age} years old, from {city}.")
introduce("Zhang San", 25, "Beijing")
introduce("Li Si", 30, "Shanghai")
パラメータの順序:位置引数
関数を呼び出すとき、引数は位置で一致します:
def create_user(name, age, is_admin):
print(f"Creating user: {name}, Age: {age}, Admin: {is_admin}")
create_user("Zhang San", 25, False) # 順序で一致
create_user(False, "Zhang San", 25) # 順序が間違っている!
例:電卓関数(難易度 ⭐)
def add(a, b):
print(f"{a} + {b} = {a + b}")
def multiply(a, b):
print(f"{a} * {b} = {a * b}")
add(5, 3) # 5 + 3 = 8
multiply(5, 3) # 5 * 3 = 15
3. 戻り値
関数は return を使って結果を呼び出し元に返せます:
def add(a, b):
return a + b
result = add(5, 3)
print(result) # 8
# 戻り値は式の中で直接使える
total = add(10, 20) + add(30, 40)
print(total) # 100
return がない場合、None を返します。これは「戻り値がない」という意味ではなく、None を返すということです。
複数の戻り値
Python は一度に複数の値を返せます(本質的にタプルを返します):
def get_min_max(numbers):
return min(numbers), max(numbers)
result = get_min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
# 結果を直接アンパック
low, high = get_min_max([3, 1, 4, 1, 5])
print(f"Min: {low}, Max: {high}")
return の動作
return は関数の実行を即座に終了し、それ以降のコードは実行されません:
def check_age(age):
if age < 0:
return "Age cannot be negative!" # 早期 return
if age < 18:
return "Minor"
return "Adult"
print(check_age(-5)) # Age cannot be negative!
print(check_age(15)) # Minor
print(check_age(25)) # Adult
例:温度変換ツール(難易度 ⭐⭐)
def celsius_to_fahrenheit(c):
"""Convert Celsius to Fahrenheit"""
return c * 9 / 5 + 32
def fahrenheit_to_celsius(f):
"""Convert Fahrenheit to Celsius"""
return (f - 32) * 5 / 9
# テスト
print(f"0°C = {celsius_to_fahrenheit(0):.1f}°F") # 32.0°F
print(f"100°C = {celsius_to_fahrenheit(100):.1f}°F") # 212.0°F
print(f"32°F = {fahrenheit_to_celsius(32):.1f}°C") # 0.0°C
print(f"212°F = {fahrenheit_to_celsius(212):.1f}°C") # 100.0°C
4. Docstring
関数定義の最初の行にある """ で書かれたコメントはdocstringと呼ばれ、関数の説明を書きます:
def calculate_bmi(weight, height):
"""
Calculate Body Mass Index (BMI)
Parameters:
weight (float): Body weight in kg
height (float): Body height in m
Returns:
float: BMI value
"""
return weight / (height ** 2)
# docstring を表示
print(calculate_bmi.__doc__)
help(calculate_bmi)
help(your_function) が何も表示しない。2)2 ヶ月後には自分でも関数が何をするか忘れます。フォーマットは強制されませんが、パラメータの説明と戻り値の説明を含めることをお勧めします。
5. 関数呼び出しスタック
関数が別の関数を呼び出すとき、Python はメモリ内に「呼び出しスタック」を維持します:
def a():
print("Entering a")
b()
print("Exiting a")
def b():
print("Entering b")
c()
print("Exiting b")
def c():
print("Entering c")
print("Exiting c")
a()
出力:
Entering a
Entering b
Entering c
Exiting c
Exiting b
Exiting a
皿を積み重ねるように——最後に置かれたものが最初に取られます。この「後入れ先出し」構造をスタックと呼びます。深くネストした関数呼び出しは「スタックオーバーフロー」を引き起こす可能性があります(例:終了条件なしの再帰)。
よくあるユースケース
- コードの再利用:繰り返されるロジックを関数に抽出し、一度定義して複数の場所から呼び出す
- モジュラープログラミング:各関数は 1 つのこと(単一責任)を行い、テストと保守が容易になる
- 計算ロジックのカプセル化:数式、データ変換、フォーマット検証などを関数にカプセル化
- フロー制御:複数戻り値の関数で複数のシナリオ(エラー、空値、正常結果)を処理
❓ よくある質問
return と print() の違いは何ですか?return は結果を呼び出し元に送り返します。print() はコンソールに出力を表示するだけです。関数が値を外部に渡すには return が必要です。print() では見えるだけで、利用することはできません。return 文を持たせられますか?return 文を持てますが、最初に実行されたものだけが動作し——関数を即座に終了します。これは条件ロジックで一般的です:異なる条件が異なる値を返します。def get_current_time(): はパラメータを必要とせず、現在時刻を直接返します(datetime モジュールを使用)。パラメータの数は、関数が外部データを必要とするかどうかに依存します。📖 まとめ
- 関数は
defで定義し、コードを再利用可能な名前付きブロックにパッケージ化 - パラメータは関数を柔軟にし、位置で一致
returnは結果を返し、関数を終了。複数の戻り値は本質的にタプルreturnのない関数はNoneを返す- docstring は
"""で関数を説明。help()で表示 - 関数呼び出しスタックは後入れ先出し構造。深いネストはスタックオーバーフローの原因に
📝 練習問題
-
初級(難易度 ⭐):関数
is_even(n)を書いてください。整数を受け取り、偶数の場合はTrue、奇数の場合はFalseを返します。%演算子を使用してください。 -
中級(難易度 ⭐⭐):関数
grade(score)を書いてください。スコア(0~100)を受け取り、対応する英字グレードを返します:90+ は「A」、80-89 は「B」、70-79 は「C」、60-69 は「D」、60 未満は「F」。if-elif で実装してください。 -
上級(難易度 ⭐⭐⭐):3 つの関数
add()、subtract()、multiply()を書いてください。次に 4 つ目の関数calculate(a, b, operator)を書いてください。2 つの数値と演算子文字列("+"、"-"、"*")を受け取り、対応する関数を呼び出して結果を返します。サポートされていない演算子の場合はNoneを返します。



