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

Python のレキシカル クロージャ動作が Perl と異なるのはなぜですか? これはどのように解決できますか?

Barbara Streisand
Barbara Streisandオリジナル
2024-12-01 14:46:13789ブラウズ

Why Does Python's Lexical Closure Behavior Differ from Perl's, and How Can This Be Resolved?

Python の字句クロージャを理解する: より深い考察

プログラミングの領域では、字句クロージャは変数へのアクセスを保持する上で重要な役割を果たします。およびそれを囲むスコープ内で定義された関数。ただし、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)

驚くべきことに、このコードは予想される「0 2」ではなく「4 4 4」を出力します。 4.」この動作を理解するには、Python の字句クロージャの性質を詳しく調べる必要があります。

Python と Perl のクロージャの動作

Python では、クロージャは変数への参照を保持します。囲むスコープ内。ただし、これらの変数がそのスコープ内で変更されると、クロージャは変更された値をキャプチャし、予期しない結果が生じます。

この動作は、クロージャが作成時に環境をキャプチャする Perl とは対照的です。 Perl コード:

my @flist = ();

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

各クロージャは作成時に $i の値をキャプチャし、期待される出力: "0 2 4."

になります。難題の解決

Python で問題に対処するには、別の関数内に関数を作成して、

flist = []

def outer():
    for i in xrange(3):
        def inner(x): return x * i
        flist.append(inner)

outer()

for f in flist:
    print f(2)

ここで、外側のループの各反復により、独自の環境と i の一意の値を持つ新しい関数が作成されます。その結果、目的の出力「0 2 4」が得られます。

結論

字句クロージャは、スコープを越えて変数や関数にアクセスするための強力なメカニズムを提供します。ただし、Python では、予期しない動作を引き起こす可能性があるため、可変変数を閉じることの影響を理解することが重要です。クロージャが作成される環境を慎重に管理することで、落とし穴を回避しながらクロージャの可能性を最大限に活用できます。

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

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