字句クロージャの複雑さを詳しく調べると、Python コードの独特な動作が明らかになります。次の例を考えてみましょう:
flist = [] for i in xrange(3): def func(x): return x * i flist.append(func) for f in flist: print f(2)
驚いたことに、このコードは、予期される "0 2 4" の代わりに "4 4 4" を出力します。この予期しない動作は、Python が字句クロージャを処理する方法に起因します。
反復ごとに新しいクロージャを作成する Perl とは異なり、Python は 3 つの個別の関数を作成します。ただし、各関数は、それが定義された環境、つまりグローバル環境のクロージャを保持します。この共有クロージャにより、すべての関数が同じ可変変数 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)
この改訂されたコードは問題を修正し、Python の動作方法における微妙だが重要な違いを示しています。 Perl は字句クロージャを処理します。使用されている特定のプログラミング言語のクロージャ動作を理解することで、開発者はそのような予期せぬ結果を回避し、より堅牢で予測可能なコードを作成できます。
以上が入れ子になったループで Python のクロージャ動作により予期しない結果が生じるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。