ホームページ > バックエンド開発 > Python チュートリアル > ループ内の Python 字句クロージャが予期しない結果を生み出すのはなぜですか?

ループ内の Python 字句クロージャが予期しない結果を生み出すのはなぜですか?

Patricia Arquette
リリース: 2024-11-29 16:57:11
オリジナル
159 人が閲覧しました

Why Do Python Lexical Closures in Loops Produce Unexpected Results?

Python の字句クロージャ: 予期しない動作を理解する

Python では、字句クロージャを使用して、内部関数が外側のスコープで定義された変数にアクセスできるようになります。ただし、共有変数を変更するループ内で関数を定義すると、予期しない動作が発生します。これを説明するために、次の Python コードを考えてみましょう:

flist = []

for i in range(3):
    def func(x): return x * i
    flist.append(func)

for f in flist:
    print(f(2))
ログイン後にコピー

このコードは "4 4 4" を出力しますが、これは "0 2 4" と予想されるので驚くべきことです。この予期しない動作の理由は、閉鎖メカニズムにあります。 Python では、ループ内で定義された関数は新しい関数を作成しますが、外側のスコープ (この場合はグローバル スコープ) を共有します。その結果、その後 i の値が変更されると、リスト内のすべての関数は同じ変更された i 値を参照します。

この問題に対処するには、ループ内の関数ごとに固有の環境を作成する必要があります。 。これは、関数クリエーターを使用することで実現できます。

flist = []

for i in range(3):
    def funcC(j):
        def func(x): return x * j
        return func
    flist.append(funcC(i))

for f in flist:
    print(f(2))
ログイン後にコピー

この改訂されたコードでは、funcC への呼び出しごとに、独自の値 i を持つ新しいクロージャー環境が生成されます。その結果、リスト内の各関数は個別の i 値にアクセスできるようになり、期待される出力は "0 2 4" になります。

この動作は、特に次のような場合に、Python でクロージャーがどのように機能するかを理解することの重要性を強調しています。副作用と関数型プログラミングを扱います。ループ内で定義された関数が変更された変数を共有すると、予期しない動作が発生する可能性があります。 Function Creator を利用すると、各関数に固有の環境を作成し、目的の動作を確実に実現できます。

以上がループ内の Python 字句クロージャが予期しない結果を生み出すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート