Python閉パッケージの理解を示す


from: https://serholiu.com/python-closures
閉パッケージという概念はJavaScriptで議論され、多く使われているが、Pythonではそれほど明らかではない.ネット上で閉包の各種の解釈に対して、感じはとても難解で、ここで私の浅い認識について話します:閉包を形成するには、まず1つのネストされた関数が必要で、つまり関数の中で別の関数を定義して、閉包は1つの集合で、それは外部の関数の局部の変数を含んで、これらの局部の変数は外部の関数が帰ってからも引き続き存在して、そして内部の関数に引用することができます.
例を挙げる
これはよく使用される例であり、1つの関数generate_power_funcを定義し、別の関数を返し、閉パケット形成の条件が達成された.
1
2
3
4
5
6
def generate_power_func(n):
    print "id(n): %X" % id(n)
    def nth_power(x):
        return x**n
    print "id(nth_power): %X" % id(nth_power)
    return nth_power

内部関数nth_powerについては、nが戻ったとしても、外部関数の局所変数generate_power_funcを参照することができる.この現象を閉包と呼ぶ.具体的に使ってみます.
1
2
3
4
5
>>> raised_to_4 = generate_power_func(4)id(n): 246F770id(nth_power): 2C090C8>>> repr(raised_to_4)''

その結果、generate_power_func(4)が実行されると、nth_powerという関数オブジェクトが作成され、戻され、メモリアドレスは0 x 2 C 090 C 8であり、raised_to_4はそのメモリアドレスと同じであることが分かった.すなわち、raised_to_4はこの関数オブジェクトの参照にすぎない.まず、generate_power_funcをグローバルネーミングスペースから削除し、どのような結果が得られるか試してみましょう.
1
2
3
>>> del generate_power_func>>> raised_to_4(2)16

ああ、間違いがなかったなんて、nth_powerはどうしてnの値が4であることを知っていますか.そして、今generate_power_funcはこのネーミングスペースにもいません.はい、これが閉パッケージの役割であり、外部関数の局所変数は、外部関数が返されても内部関数によって参照できます.
__closure__ プロパティとcellオブジェクト
今は閉鎖がどういうことか知っていますが、閉鎖がいったいどういうことなのかを見る時です.Pythonでは関数もオブジェクトなので、関数にも多くの属性があり、閉パッケージに関連するのが__closure__属性です.__closure__プロパティは、cellオブジェクトを含むメタグループを定義し、メタグループ内の各cellオブジェクトは、役割ドメイン内の変数の値を保存するために使用されます.
1
2
3
4
5
6
>>> raised_to_4.__closure__(,)>>> type(raised_to_4.__closure__[0])>>> raised_to_4.__closure__[0].cell_contents4

先ほど述べたように、raised_to_4__closure__属性には外部関数変数nの参照があり、メモリアドレスから同じnが参照されていることがわかります.閉パケットを形成する必要がない場合、__closure__属性はNoneである.Pythonが具体的にどのように閉パケットを実現するかについては、Pythonの閉パケットの詳細を表示することができ、Pythonバイトコードを分析することによって閉パケットの実現を説明する.
最後にまとめる
クローズドパッケージの特性は非常に多くの役割を果たしていますが、必要に応じて何気なく使用し、設計モードのようにこれらの法則を無理にカバーしないでください.この文章は自分の理解に従ってPython Closures Explainedに翻訳して、原文と少し異なっているかもしれませんが、疑問があれば、原文を見てください.参考資料を添付します.
  • 閉パケットの概念、形式と応用:閉パケットの応用
  • を理解することができる.
  • Python閉パケット詳細:バイトコードからPython閉パケットの実現メカニズム
  • を理解する.
  • Javascriptの閉パッケージを理解する:Javascriptの閉パッケージからいくつかの閉パッケージ特性を理解し、Pythonと比較することができる