ホームページ >バックエンド開発 >Python チュートリアル >Python のループ内の Lambda 関数が予期しない動作を示すのはなぜですか?
ループ内のラムダ: デフォルトのクロージャ パラメーターについて理解する
Python プログラミングでは、ラムダ関数は動的コードの作成に使用できる匿名関数です。ブロック。ただし、ループ内でラムダを使用すると、予期しない動作が発生する可能性があります。この記事では、この問題を調査し、解決策を示します。
次のコード スニペットを考えてみましょう:
# directorys == {'login': <object at ...>, 'home': <object at ...>} for d in directorys: self.command["cd " + d] = (lambda: self.root.change_directory(d))
目的は、コマンドを関数にマップする辞書 self.command を作成することです。各関数は、ディレクトリをディレクトリ内の指定された値に変更する必要があります。ただし、結果は予期せぬものになります:
# Expected: self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("home") } # Result: self.command == { "cd login": lambda: self.root.change_directory("login"), "cd home": lambda: self.root.change_directory("login") # <- Why login? }
この問題は、ループ内で作成されたラムダ関数が同じクロージャを共有するために発生します。ループ内で d が更新されると、すべてのラムダ関数に影響があり、それらの関数が同じ変数を参照するようになります。
解決策: デフォルトのクロージャ パラメーターを使用する
これを解決するには、デフォルトのクロージャパラメータを導入します。その方法は次のとおりです。
lambda d=d: self.root.change_directory(d)
デフォルト値を持つパラメーターとして d を渡すことにより、ラムダ内の関数はループ変数の代わりに独自のパラメーターを参照します。これにより、各関数がディレクトリを意図した値に変更することが保証されます。
# Another way to bind d: lambda bound_d=d: self.root.change_directory(bound_d)
可変オブジェクト (リストや辞書など) のデフォルト値は共有されることに注意してください。そのため、これらの型をバインドするときは注意してください。
追加のクロージャ手法
デフォルトのパラメータを渡すことが理想的でない場合は、これらの代替クロージャを試してくださいテクニック:
ネストされたクロージャ:
(lambda d: lambda: self.root.change_directory(d))(d)
即時呼び出し:
(lambda d=d: lambda: self.root.change_directory(d))()
以上がPython のループ内の Lambda 関数が予期しない動作を示すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。