ホームページ >バックエンド開発 >Python チュートリアル >この Python クロージャの例では、「0 2 4」ではなく「4 4 4」が出力されるのはなぜですか?

この Python クロージャの例では、「0 2 4」ではなく「4 4 4」が出力されるのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-29 08:12:10260ブラウズ

Why Does This Python Closure Example Print

字句クロージャを理解する: 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。