嘗試使用閉包從函數簽章中刪除變數時,您可能會遇到意外行為。具體來說,未包含在另一個函數中的 lambda 函數會傳回所有實例的變數的最後一個值。
要理解此行為,重要的是要認識到閉包捕獲名稱而不是值。當您將 lambda 定義為 lambda x: test_fun(n, x) 時,n 變數不會在函數內計算,而是在呼叫時計算。因此,它假定的值是循環中的最後一個值。
要使用閉包有效地「消除」變量,必須將該變數作為參數傳遞給函數。這會將變數的當前值分配給函數並有效地「鎖定它」。例如:
<code class="python">stuff = [lambda x: n+x for n in [1, 2, 3]] # Bad, captured value is last value stuff = [lambda x, n=n: n+x for n in [1, 2, 3]] # Good, n is locked in</code>
或者,您可以使用兩個巢狀函數:
<code class="python">def makeFunc(n): return lambda x: x+n stuff = [makeFunc(n) for n in [1, 2, 3]]</code>
這裡,makeFunc 中的 lambda 來擷取局部 n 變數而不是全域變數。每個 makeFunc 呼叫都會建立一個新的局部變量,確保傳回的 lambda 函數具有唯一的 n 值。
最終,簡單性和靈活性之間的選擇取決於您。您可以選擇在傳回的函數中使用額外參數來建立更簡單的函數,也可以選擇使用涉及兩個巢狀函數的更複雜的函數建立過程來建立更乾淨的函數。
以上是為什麼 Lambda 閉包捕獲名稱而不是值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!