ホームページ >バックエンド開発 >Python チュートリアル >Python のレキシカル クロージャ動作が Perl と異なるのはなぜですか?

Python のレキシカル クロージャ動作が Perl と異なるのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-12 16:42:10123ブラウズ

Why Does Python's Lexical Closure Behavior Differ from Perl's?

Python と Perl の字句クロージャの解読

JavaScript で字句クロージャを調査していると、Python での字句クロージャの独特な動作について疑問が生じます。次の 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" が出力されます。

対照的に、この同等の Perl コードは目的の結果を生成します。結果:

my @flist = ();

foreach my $i (0 .. 2)
{
    push(@flist, sub {$i * $_[0]});
}

foreach my $f (@flist)
{
    print $f->(2), "\n";
}

基礎となるもの違い

主な違いは、クロージャがその環境をどのようにキャプチャするかにあります。

  • Python: ループ内で作成された関数はすべて、ループのクロージャを共有します。環境。ループ変数 i が変更されると、すべての関数は同じ変更された i を参照します。
  • Perl: ループ内で作成された関数はそれぞれ独自のクロージャを持ち、作成時に i の値をキャプチャします。

Python ソリューション

Python で予期される動作が行われない場合は、関数ごとに別の環境を強制する必要があります。解決策の 1 つは、異なるクロージャを持つ関数を返す関数作成ツールを作成することです。

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)

このメソッドでは、各関数が独自の固有の i 値を持つ独自のクロージャを持つことが保証されます。

以上がPython のレキシカル クロージャ動作が Perl と異なるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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