Python での予期しない Lambda クロージャ動作の原因は何ですか?

Mary-Kate Olsen
リリース: 2024-10-21 13:10:30
オリジナル
884 人が閲覧しました

What Causes Unexpected Lambda Closure Behavior in Python?

Python ラムダ クロージャのスコープ

Python でのラムダ クロージャの動作を理解するのは難しい場合があります。この記事では、ラムダ関数が予期せぬ動作をし、すべてのケースで同じ値を返すケースについて説明します。

問題:

次のコードを考えてみましょう:

<code class="python">names = ['a', 'b', 'c']

def test_fun(name, x):
    print(name, x)

def gen_clousure(name):
    return lambda x: test_fun(name, x)

funcs1 = [gen_clousure(n) for n in names]
funcs2 = [lambda x: test_fun(n, x) for n in names]</code>
ログイン後にコピー

funcs1 の関数を呼び出すと、予期した出力が得られます:

a 1
b 1
c 1
ログイン後にコピー

しかし、funcs2 の関数を呼び出すと、予期しない結果が得られます:

c 1
c 1
c 1
ログイン後にコピー

予期される出力は最初のケースと同じであるはずですが、代わりに、すべてのケースで姓 'c' の値が表示されます。

説明:

この動作を理解する鍵は、クロージャの概念にあります。 Python のクロージャを使用すると、内部関数が外側のスコープから変数にアクセスできるようになります。最初のケース (funcs1) では、ラムダ関数はループ内で作成されますが、変数名を囲んでいるスコープから取得し、それをラムダ関数内の名前にバインドします。

2 番目のケース (funcs2) ) ただし、ラムダ関数は、変数 n をラムダ関数内の名前にバインドせずに、囲んでいるスコープから直接参照します。これは、ラムダ関数が呼び出されると、その時点で n が評価され、常にループからの最後の値が返されるため、予期しない出力が発生することを意味します。

問題の回避:

この問題を回避し、望ましい動作を実現するには、ラムダ関数が周囲のスコープから変数を取得し、それをラムダ関数内の名前にバインドすることを確認する必要があります。これを行う 1 つの方法は、ラムダ関数を別の関数でラップすることです。

<code class="python">def makeFunc(n):
    return lambda x: x+n</code>
ログイン後にコピー

makeFunc の結果として得られるラムダ関数は、囲んでいるスコープから n の値を取得し、それをラムダ関数内の名前にバインドします。望ましい動作を実現します。

以上がPython での予期しない Lambda クロージャ動作の原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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