所以我有這個簡單的演示來解決我的問題:
from functools import partial
import tkinter as tk
root = tk.Tk()
root.title("Test")
root.geometry("400x400")
colors = ["red", "green", "blue"]
for x in range(3):
firstFrame = tk.Frame(root, bg=colors[x])
firstFrame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
firstFrame.bind("<Enter>", lambda e: print(f"Enter: {x}"))
firstFrame.bind("<Leave>", lambda e: partial(print, f"Leave: {x}")())
root.mainloop()
當我運行代碼并將滑鼠懸停在紅色部分上,然后是綠色部分,最后是藍色部分,然后關閉視窗,我得到以下輸出:
Enter: 2
Leave: 2
Enter: 2
Leave: 2
Enter: 2
Leave: 2
我需要的是:
Enter: 0
Leave: 0
Enter: 1
Leave: 1
Enter: 2
Leave: 2
如您所見,我嘗試了多種方法來獲得所需的輸出,例如使用partial創建一個全新的函式而不是簡單地呼叫print,但沒有產生任何結果。
uj5u.com熱心網友回復:
這是 Python lambda 中的常見問題。回圈變數只存在一次,因此如果在回圈for內創建 lambda for,則 lambda 將捕獲變數不斷變化的可變值。
解決這個問題的訣竅是利用 Python 的默認引數。當為函式創建默認引數時,它實際上會在該函式物件上創建一個新屬性,以存盤變數的當前值。這是一個單獨的變數,因此回圈變數的未來重新分配不會影響默認引數的值。
firstFrame.bind("<Enter>", lambda e, arg=x: print(f"Enter: {arg}"))
您會看到人們將默認引數命名為與封閉變數相同的名稱。以下代碼段與前者完全相同;xlambda的引數隱藏了回圈中的引數。xfor
firstFrame.bind("<Enter>", lambda e, x=x: print(f"Enter: {x}"))
這只是減少了程式員在概念上相同變數的兩個變數名稱之間切換的認知負擔。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/510576.html
