Pythonにおけるクロージャー
クロージャー(closure)とは、 関数と、その関数がアクセス可能なすべての 外部変数をまとめたものを意味します。
Pythonでは、「関数のクロージャー」と言う場合、 多くの場合、その関数自体ではなく、 まさにその外部変数を指しています。
ここに、変数iを宣言し、
内部関数innerを持つ関数outerがあるとします。
内部関数内ではiに1が加算されます。
変数iが正しく動作するために、
キーワードnonlocalを追加します:
def outer():
i = 0
def inner():
nonlocal i
i += 1
print(i)
return inner
では、外側の関数を変数resに代入し、
括弧を付けて呼び出してみましょう:
res = outer()
res() # 1を出力
resを数回呼び出してみましょう。
コードを実行するたびに、カウンターiが
1ずつ増加します:
res() # 2を出力
res() # 3を出力
res() # 4を出力
しかし、ここには重要なニュアンスがあります。
関数outerを呼び出すたびに、それぞれ独自のカウンターが
増加します。最初のouterの呼び出しを
変数res1に、2回目の呼び出しを
変数res2に代入してみましょう。
次に、それらを順番にコンソールに出力します:
res1 = outer()
res1() # 1を出力
res1() # 2を出力
res1() # 3を出力
res2 = outer()
res2() # 1を出力
res2() # 2を出力
res2() # 3を出力
次のコードがあります:
def outer():
i = 10
def inner():
nonlocal i
i -= 2
print(i)
return inner
res1 = outer()
res1()
res1()
res2 = outer()
res2()
res2()
res2()
コンソールに何が出力されるか答えてください。
呼び出されるたびに次のフィボナッチ数を返す 関数を作成してください。
ある範囲内でランダムな整数を生成する関数を作成してください。 ただし、連続して同じ数が2回出ないようにしてください。