1. ホーム
  2. パイソン

[解決済み】なぜpythonのネストされた関数はクロージャと呼ばれないのですか?

2022-04-15 21:57:05

質問

Pythonでネストされた関数を見たことも使ったこともありますが、クロージャの定義に合致しています。 では、なぜ nested functions ではなく closures ?

ネストされた関数は外部で使用されないのでクロージャではないのでしょうか?

UPDATEです。 クロージャについて読んでいて、Pythonに関するこの概念について考えるようになりました。検索したところ、下のコメントでどなたかが紹介されている記事を見つけましたが、その記事の説明を完全に理解できなかったので、この質問をさせていただきました。

どのように解決するのですか?

クロージャは、関数が実行を終了したスコープからローカル変数にアクセスできるようになったときに発生します。

def make_printer(msg):
    def printer():
        print(msg)
    return printer

printer = make_printer('Foo!')
printer()

いつ make_printer が呼び出されると、新しいフレームがスタックに置かれ、その中に printer 関数を定数とし msg をローカルとして使用します。そして、その関数を生成して返す。なぜなら、関数 printer を参照しています。 msg 変数がある場合、それは make_printer 関数が返される。

そのため、ネストした関数が

  1. は、包含するスコープにローカルな変数にアクセスします。
  2. そのスコープの外側で実行されたときにそうする。

であれば、クロージャではありません。

クロージャではないネストされた関数の例です。

def make_printer(msg):
    def printer(msg=msg):
        print(msg)
    return printer

printer = make_printer("Foo!")
printer()  #Output: Foo!

ここでは、パラメータのデフォルト値に値をバインドしています。この現象は、関数 printer が作成されるので、その値への参照はありません。 msg の外部にある printer の後に維持する必要があります。 make_printer を返します。 msg は単なる関数の通常のローカル変数です。 printer というように、この文脈では