Python閉パッケージの理解を示す
from: https://serholiu.com/python-closures
閉パッケージという概念はJavaScriptで議論され、多く使われているが、Pythonではそれほど明らかではない.ネット上で閉包の各種の解釈に対して、感じはとても難解で、ここで私の浅い認識について話します:閉包を形成するには、まず1つのネストされた関数が必要で、つまり関数の中で別の関数を定義して、閉包は1つの集合で、それは外部の関数の局部の変数を含んで、これらの局部の変数は外部の関数が帰ってからも引き続き存在して、そして内部の関数に引用することができます.
例を挙げる
これはよく使用される例であり、1つの関数
内部関数
その結果、
ああ、間違いがなかったなんて、
__closure__ プロパティとcellオブジェクト
今は閉鎖がどういうことか知っていますが、閉鎖がいったいどういうことなのかを見る時です.Pythonでは関数もオブジェクトなので、関数にも多くの属性があり、閉パッケージに関連するのが
先ほど述べたように、
最後にまとめる
クローズドパッケージの特性は非常に多くの役割を果たしていますが、必要に応じて何気なく使用し、設計モードのようにこれらの法則を無理にカバーしないでください.この文章は自分の理解に従ってPython Closures Explainedに翻訳して、原文と少し異なっているかもしれませんが、疑問があれば、原文を見てください.参考資料を添付します.閉パケットの概念、形式と応用:閉パケットの応用 を理解することができる. Python閉パケット詳細:バイトコードからPython閉パケットの実現メカニズム を理解する. Javascriptの閉パッケージを理解する:Javascriptの閉パッケージからいくつかの閉パッケージ特性を理解し、Pythonと比較することができる
閉パッケージという概念は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に翻訳して、原文と少し異なっているかもしれませんが、疑問があれば、原文を見てください.参考資料を添付します.