次のコード スニペットを考えてみましょう:
# directorys == {'login': <object at ...>, 'home': <object at ...>} for d in directorys: self.command["cd " + d] = (lambda : self.root.change_directory(d))
目標は、キーを持つ 2 つの関数の辞書を作成することです。 「CD ログイン」と「CD ホーム」。ただし、結果は、両方のラムダ関数がキー「cd login」を持つ同じ内容を持っていることを示しています。
この予期しない動作を理解するには、入れ子になったループでラムダ関数がどのように動作するかを考慮することが重要です。ラムダ関数がループ内で定義されると、周囲のスコープから変数をキャプチャします。この場合、ループからの変数 d は各ラムダ関数によってキャプチャされます。
ただし、ラムダ関数は遅延実行されます。したがって、ループの外側で self.command ディクショナリにアクセスすると、すべてのラムダ関数が同じ d 変数、つまりループ内の d の最後の値をキャプチャします。したがって、すべての関数が同じメソッドを指し、観察される動作が生じます。
この問題を解決するには、各ラムダ関数が d の個別の値を確実に取得する必要があります。解決策の 1 つは、d をパラメータとしてラムダ関数に渡し、デフォルト値を指定することです。
lambda d=d: self.root.change_directory(d)
これで、ラムダ関数内の d は、同じ名前であってもパラメータを使用します。このパラメータのデフォルト値は関数の作成時に評価され、ループの反復ごとに d の正しい値にバインドされます。
または、ネストされたクロージャを使用して同じ結果を達成することもできます。
(lambda d: lambda: self.root.change_directory(d))(d)
以上がループ内の Lambda 関数が各反復の値ではなく最後の値を取得するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。