首頁 >後端開發 >Python教學 >為什麼 Python 循環中的 Lambda 函數會出現意外行為?

為什麼 Python 循環中的 Lambda 函數會出現意外行為?

Patricia Arquette
Patricia Arquette原創
2024-12-28 10:35:11107瀏覽

Why Do Lambda Functions in Loops in Python Exhibit Unexpected Behavior?

循環中的Lambda:了解預設閉包參數

在Python 程式設計中,lambda 函數是可用於建立動態程式碼的匿名函數塊。然而,在循環中使用 lambda 時,可能會遇到意外行為。本文探討了該問題並提供了解決方案。

考慮以下程式碼片段:

# 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?
}

問題的出現​​是因為在循環中創建的 lambda 函數共享相同的閉包。當 d 在迴圈中更新時,它會影響所有 lambda 函數,導致它們引用同一個變數。

解決方案:使用預設閉包參數

解決此問題,引入預設閉包參數。具體方法如下:

lambda d=d: self.root.change_directory(d)

透過將 d 作為具有預設值的參數傳遞,lambda 中的函數將引用其自己的參數而不是循環變數。這可確保每個函數將目錄變更為預期值。

# 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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn