一、コード解説
def power(exponent): def inner(base): return base ** exponent return inner
この関数powerは高階関数で、別の関数innerを返します。コードを段階的に見ていきましょう:
1. power(exponent)は外部関数で、引数exponentを受け取ります。
2. power関数内で、別の関数inner(base)が定義されています。この関数は引数baseを受け取り、base ** exponentを返します。
3. 最も重要な行:return inner
この行では、内部で定義された関数innerを呼び出し元に返します。つまり、power関数が返すのは関数オブジェクトで、関数が定義されたときのスコープ内の変数exponentを覚えています。
二、クロージャの概念
クロージャ(Closure)は、関数がその定義時に存在していたスコープ内の変数を「覚えている」ものです。この変数は、関数が実行された後でも保持されます。
上記の例では:
- power(2)が呼び出されると、inner関数オブジェクトが返され、変数squareに代入されます。
- power関数が実行されると、ローカル変数exponentは通常は破棄されるべきですが、inner関数がexponentを使っているため、Pythonはexponentをinnerの「環境」に保持し、クロージャが形成されます。
- そのため、power関数が終了した後でも、square(3)はexponent = 2を使用して3 ** 2を計算できます。
これがクロージャです。
三、クロージャの実行過程を可視化
square = power(2) # この時、exponent = 2が「記憶」される print(square(3)) # 実際にはinner(3)が呼ばれ、3 ** 2 = 9が返される
他のクロージャを定義することもできます:
cube = power(3) print(cube(2)) # 出力は8、2 ** 3 = 8だから
これにより、squareとcubeは異なるクロージャ関数であり、それぞれ異なるexponent(2と3)を「記憶」していることが分かります。