ホームページ >バックエンド開発 >Python チュートリアル >この Python クロージャの例では、「0 2 4」ではなく「4 4 4」が出力されるのはなぜですか?
字句クロージャを理解する: Python の難題
関数型プログラミングの領域では、字句クロージャは重要な役割を果たします。ただし、特定のプログラミング言語では、その動作を理解する際に複雑さが生じる場合があります。たとえば、Python は、クロージャと環境の相互作用を示す興味深いパズルを提供します。
次の Python コード スニペットは例として機能します:
flist = [] for i in xrange(3): def func(x): return x * i flist.append(func) for f in flist: print f(2)
このコードは驚くべきことに "4 4" を出力します。予想される「0 2 4」ではなく、「4」です。最初はグローバル変数 i が関数間で共有されているのではないかと疑うかもしれませんが、入れ子関数内で i がローカルに宣言されている場合でも問題は残ります。
この動作を理解する鍵は、クロージャの概念にあります。 Python では、入れ子になった各関数は、それを含むスコープのクロージャーを保持します。この場合、入れ子になった関数は、可変変数 i を含むグローバル環境のクロージャを共有します。ループ中に i が変更されると、すべての関数は変更された値を参照します。
この問題を回避し、望ましい動作を保証するには、関数作成者のアプローチに頼ることができます。関数をインラインで作成する代わりにクリエーター関数を呼び出すことにより、作成された関数ごとに個別の環境が確立されます。
修正されたコードの例を次に示します:
flist = [] for i in xrange(3): def funcC(j): def func(x): return x * j return func flist.append(funcC(i)) for f in flist: print f(2)
このアプローチでは、効果的に個別の関数を生成します。独自のクロージャであり、期待される出力 "0 2 4" が得られます。
したがって、クロージャは強力な機能を提供しますが、環境との相互作用により、微妙な複雑さを導入します。クロージャの可能性を最大限に活用するには、クロージャの範囲とニュアンスを慎重に検討することが不可欠です。
以上がこの Python クロージャの例では、「0 2 4」ではなく「4 4 4」が出力されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。