4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

クロージャのイメージ図

Posted at

はじめに

今回の質問(Qiitaでの質問ではありません)

クロージャで外側の変数が参照できるというのは理解できるが納得はできない。関数内の変数1(引数含む)は関数が終了したら消えるのではないか?変数はどこかに保持されてるのだろうけど具体的にどこにあるのか。

これに対して

「まずはそういうものだと思わないといけない。それ以上知りたいのならPythonのソースを読まないといけない。ちなみに関数(クロージャ)に結び付けられている」

と答えたのですが、もう少し考えたところ、

「そもそも関数が終了したら変数が消えるという概念自体どこから学んだのか(消えるけど)。なお言語実装に関する知識(つまりスタック上に変数が確保される2という知識)はないものとする」

ということが気になりました。
そんなわけで今回はここら辺の概念を絵で説明しようと思います。

関数と変数と関数の終わり

クロージャの前にまず普通の関数です。

普通の関数
def add(a, b):
    return a + b

add(2, 3)

最終行ではaを2、bを3としてのaddの呼び出しが行われます。これを図に描くと以下のようになります。

func_exec_state1.png

「addの実行状態」としているのはこの後で説明する「関数が終了する際の動作」のためですが(「add」とすると話が正確でなくなります)、ともかく「2」というオブジェクトに対して実行状態からaの矢印、「3」というオブジェクトに対してbの矢印が出ています。a, bが上下逆なのはこの後で描く図に合わせるためなのであまり気にしないでください。

addが終了するときには「addの実行状態」が消えます。すると当然実行状態から出ているa, bの矢印も消えます。これが「関数が終了すると変数が消える」状況です。

func_exec_state2.png

クロージャと変数

さてここまでで「関数が実行されるときの変数のイメージ」、「関数が終了するときの変数のイメージ」を説明してきました。これを踏まえてクロージャに進みましょう。なお無駄なb変数がいますが話の都合です。

クロージャ
def make_adder(a, b):
    def adder(x):
        return x + a
    return adder

adder3 = make_adder(2, 3)
adder3(4)

make_adder(2, 3)呼び出しが行われ、make_adderreturn手前(つまりadderが定義された後)時点を図に描くと以下のようになります。つまり、aが指している「2」はmake_adder(の実行状態)からもadderからも参照されていることになります。3

func_exec_state3.png

make_adderが終了するときには普通の変数と同様に実行状態が消えます。ただし、青で書いているadder本体はreturnされているので消えません。そして、adderから参照されているa(が指す「2」)も消えません。

func_exec_state4.png

このようにしてa(が参照しているもの)が残るため、その後にadder3(4)と呼び出されると保存されていた「2」を取り出して使うことが可能になります。

closure_exec_state.png

おしまい。
あっ、nonlocalは多分もう少しめんどくさいことしてると思いますが調べたことないので省きます。

参考

【Python】クロージャ(関数閉方)とは
変数がどう保存されているのか等について詳しく書かれています。

Pythonを読む/クロージャ
2年半ほど前に「クロージャの実装詳細」を読んだ時のメモです。

  1. 正確には変数が参照しているオブジェクト

  2. ここら辺の詳しい話はこちらもご参照ください

  3. 「make_adder実行状態」から出ている矢印も指されているものもadderとなっていますがこれは「関数自体にadderという名前が付いている」ので誤りではありません。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?