Pythonでは、関数の内部にさらに別の関数を定義することができます。これを「内部関数」や「ネスト関数(入れ子関数)」と呼びます。
一見すると複雑に見えるかもしれませんが、特定の処理をその関数内だけで使い回したい場合や、外部から処理を隠蔽したい場合に非常に有効なテクニックです。
この記事では、内部関数の基本的な定義方法と、その利用メリットについて解説します。
目次
内部関数の基本構文
内部関数は、通常の関数定義(def)の中に、インデントを下げて別の def を記述することで作成します。
構文:
def 外側の関数():
# 外側の処理
def 内側の関数():
# 内側の処理
# 外側の関数内で、内側の関数を呼び出す
内側の関数()
重要なルールとして、内部関数は、それが定義された「外側の関数」の中でしか呼び出すことができません。グローバルスコープ(関数の外)から直接内部関数を呼び出そうとするとエラーになります。
具体的なコード例:テキスト処理のヘルパー関数
内部関数の典型的な使い道は、メインの関数内で行う「繰り返しの処理」や「細かいサブルーチン」をまとめることです。
例として、ユーザーへの挨拶メッセージを作成する関数を考えます。この関数内で、「名前をフォーマットする(敬称をつける、空白を除く)」という処理を内部関数として定義します。
def create_greeting_message(user_name):
"""
ユーザー名を受け取り、フォーマットして挨拶を返す関数
"""
# --- 内部関数の定義 ---
def format_name(name):
"""
名前の前後の空白を除去し、'様' を付ける内部関数
"""
clean_name = name.strip()
if not clean_name:
return "ゲスト様"
return f"{clean_name}様"
# ----------------------
# 内部関数を利用して処理を行う
formatted_name = format_name(user_name)
message = f"こんにちは、{formatted_name}。今日も良い一日を!"
return message
# --- 関数の実行 ---
print(create_greeting_message(" Tanaka "))
print(create_greeting_message(""))
実行結果:
こんにちは、Tanaka様。今日も良い一日を!
こんにちは、ゲスト様。今日も良い一日を!
解説
create_greeting_messageが呼び出されると、その中でformat_name関数が定義されます。format_name(user_name)を実行し、名前の整形を行います。- この
format_name関数は、create_greeting_messageの外側からは見えないため、他の場所で名前が衝突する心配がありません。
内部関数のメリット
- 名前空間の汚染を防ぐ(カプセル化) その関数内でしか使わない補助的な関数を内部に隠蔽することで、グローバルな名前空間に関数が増えるのを防ぎます。
- コードの可読性向上 「この関数はここでしか使われない」という意図が明確になり、コードの構造が理解しやすくなります。
- 外側の変数の参照(クロージャ) 内部関数は、外側の関数の変数(ローカル変数)にアクセスできます。これを利用して、状態を保持する関数(クロージャ)を作成することも可能です。
スコープの確認
内部関数が外部から呼び出せないことを確認します。
# 外側の関数を実行しても、内部関数が外に漏れることはない
create_greeting_message("Suzuki")
# 外部から内部関数を呼ぼうとするとエラーになる
# format_name("Sato")
# NameError: name 'format_name' is not defined
まとめ
- 関数の中に
defを書くことで内部関数を定義できます。 - 内部関数は、外側の関数の中からのみ呼び出し可能です。
- 処理を部品化し、外部から隠蔽することで、整理された安全なコードを書くのに役立ちます。
