【Python】クロージャとは?|サックリかんたん解説

初心者向けサックリかんたん解説

ここでは一通りPythonを勉強した私が「ここはわかりづらいだろうな」と思った点や、最近Pythonの勉強をし始めたという初心者の方がつまづきがちな点をピックアップし、長ったらしくならないようできるだけ簡単にサクッと解説していきます。

クロージャ (closure) とは

クロージャとは、

  • ほかの関数によって生成される関数で、
  • その関数の外で定義された変数の値を覚えて置いたり、変えたりすることが出来る

ものになります。

ちなみにこのように、ほかの関数の中で宣言される関数を、関数内関数といいます。

百聞は一見に如かず、実際にクロージャの簡単な例を見てみましょう。


1: def outer():  # 外側の関数outer
2:     outer_var = 10  # 外側の関数内で宣言された変数
3:     def inner(x):  # 内側の関数 inner
4:         return x*outer_var 
5:     return inner
6: 
7: func = outer()  # inner型の関数オブジェクトを生成し、func変数に代入
8: print(func(5))

こちらを実行すると次のような結果になります。


実行結果>>> 50

このコードをみて、「あれ?関数の外で宣言されているouter_varの値になんでアクセスできるの?おかしいんじゃ?」と思った方もいるかもしれません。

答えから言うと、大丈夫です。なぜなら7行目でouterという関数オブジェクトを生成する瞬間にouter_varへのアクセスが許可されます。
その次に、outer関数はinnerという関数内関数を戻り値として返す関数であることから、innerの中で処理が始まります。その処理がこちら


4:         return x*outer_var

ここで、outer_varという変数の値を探しにいくわけですが、inner関数内にはそのような変数は宣言されていません。

そうなると、inner関数のすぐ外側の関数であるouter関数の中にそのような変数がないかを探しに行くわけです。
すると、outer関数にはそのような変数があるのでその値を参照します。
(この理屈が分からないという方はスコープという概念について調べてみてください。)

そして最後に、このようにして作られた関数オブジェクトをfuncという変数に代入することで、inner型の関数を作ることができました。
このfuncの中身はどういったものになっているかというと次のようになっています。


1: def func(x):
2:     return x*10

冒頭で、”クロージャはほかの関数(outer関数)によって生成される関数(inner関数)で、その関数(inner関数)の外で作られた変数(outer_var)の値を覚えておくことができる”といったはずです。
まさにその通りになっていますね。

これがクロージャです。理解できたでしょうか。

つまりクロージャはなにしてるの?

クロージャはクラスに似ています

クラスでは設計図から実体(インスタンス)となるオブジェクトを生成していくように、
クロージャは関数内関数の構造で関数オブジェクトを生成します。

ちなみに、クロージャは”closure: 閉じこめること”と書きますが、何を closeしている(閉じ込めている) かというと、
”内側の関数の外側の関数で宣言された変数の値”を内側の関数内に閉じ込めていると考えるとイメージしやすくなるのではないでしょうか。

終わりに

ここまで見てくださってありがとうございました!

出来るだけわかりやすく書いたつもりですが、それでもわからなかったという方は申し訳ないです。
そういった方は、クラスやスコープについて調べてからもう一度見るとわかりやすいかもしれません。

クロージャはJavaScriptなどで有名なイメージがありますが、Python にもクロージャの概念があります。
クロージャは必須知識というわけではないですが大事な知識だと思いますので習得しておきましょう。

※こちらの解説は「入門Python3」という本を参考にしました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です