Python

【Python】第3章第13回:クロージャー(closure)の基本

本記事では、Pythonにおけるクロージャー(closure)の基本概念とその活用方法について解説します。クロージャーを活用することで、関数のスコープやデータのカプセル化を効率的に管理できます。

0. 記事の概要

この記事を読むメリット

  • クロージャーの基本を理解:クロージャーがどのように動作するかを学べます。
  • 応用スキルの習得:クロージャーを使った実践的な設計方法を習得できます。
  • スコープの深い理解:関数スコープと変数の扱いについての知識が深まります。

この記事で学べること

  • クロージャーの基本的な仕組み
  • クロージャーの実践的な応用例
  • クロージャーを利用する際の注意点

1. クロージャーの基本

1.1 クロージャーとは?

クロージャーとは、関数がそのスコープ外で呼び出された後も、外部スコープの変数を保持し続ける関数のことです。

# クロージャーの基本例
def outer_function(message):
    def inner_function():
        print(message)
    return inner_function

closure = outer_function("こんにちは、Python!")
closure()  # "こんにちは、Python!" が出力される
動作解説
  1. inner_functionouter_function内で定義されており、外部スコープのmessage変数にアクセスします。
  2. outer_functionが終了しても、message変数はクロージャー内で保持されます。
  3. closure()を呼び出すと、inner_functionが実行され、messageの内容が出力されます。

2. クロージャーの実践例

2.1 データのカプセル化

クロージャーはデータを隠蔽し、外部からの不正なアクセスを防ぐために使用できます。

# カプセル化の例
def make_counter():
    count = 0

    def counter():
        nonlocal count
        count += 1
        return count

    return counter

counter_instance = make_counter()
print(counter_instance())  # 1
print(counter_instance())  # 2
動作解説
  1. count変数はmake_counterのスコープ内にありますが、counter関数内でアクセスできます。
  2. nonlocalキーワードを使用することで、countを変更可能にしています。
  3. make_counterが終了しても、クロージャーがcountを保持します。

2.2 パラメータ化された関数の生成

クロージャーを使うと、特定のパラメータに基づいた関数を生成できます。

# 掛け算関数を生成
def multiplier(factor):
    def multiply_by(x):
        return x * factor
    return multiply_by

times_three = multiplier(3)
print(times_three(10))  # 30

3. クロージャーを使う際の注意点

3.1 大量のデータを保持しない

クロージャーが外部スコープの変数を保持するため、メモリ使用量に注意が必要です。

3.2 変数のスコープに注意

nonlocalを使用して変数を変更する場合、意図せず値を上書きしないように注意しましょう。

4. 練習問題

以下の課題に挑戦してみましょう。

  1. クロージャーを使って、指定された文字列を繰り返し出力する関数を作成してください。
  2. クロージャーを利用して、リスト内の要素を指定回数掛け合わせる関数を作成してください。

5. 練習問題の解答と解説

問1の解答例

# 繰り返し文字列出力
def string_repeater(string):
    def repeat():
        return string * 3
    return repeat

repeater = string_repeater("Python")
print(repeater())  # "PythonPythonPython"

問2の解答例

# 要素を指定回数掛け合わせる関数
def list_multiplier(factor):
    def multiply_list(lst):
        return [x * factor for x in lst]
    return multiply_list

multiplier = list_multiplier(2)
print(multiplier([1, 2, 3]))  # [2, 4, 6]

6. まとめ

クロージャーは、データのカプセル化や動的に関数を生成する際に非常に有用です。練習問題を通じて、クロージャーの概念と応用スキルを深めてください。