При изменении переменной меняется и аргумент в lambda python
Я получаю информацию из файла, а потом вызываю функцию select_user.
Вот упрощённая версия кода:
from tkinter import * # Использую tkinter для графического интерфейса
a_txt = open("a.txt", encoding = "utf8").read() # Читает файл a.txt
a = {}
for i in a_txt.split("\n"): # При каждой строке файла выполняет следующее
a_tab = a.split("\t")
a[a_tab[0]] = a_tab[1] # Обнаруживая таб в файле, разделяет его на две части и записывает в a
tk = Tk()
def select_user(clid):
print(clid)
for name, clid in a.items():
b = Button(tk, text = name, command = lambda: select_user(clid)) # Создаёт кнопку
b.place(relx = 0.034, rely = 0.08) # Размещает кнопку на экране (в оригинальном коде они помещаются на экран в разные места)
Вот файл a.txt (вместо четырёх пробелов там табы):
Название1 0
Название2 1
Название3 2
Проблема заключается в том, что аргумент clid изменяется с каждой итерацией for и при нажатии кнопки передаётся самый последний результат.
Вот результат нажатия на 3 разные кнопки:
2
2
2
Есть ли возможность как-нибудь по другому вызвать функцию с аргументом (и чтобы аргумент не менялся) при нажатии кнопки в tkinter?
Надо сделать так, чтобы при нажатии на первую кнопку чтобы результатом был 0, на вторую 1, а на третью 2
Ответы (1 шт):
Это поведение особенность лямбд при циклах. Чтобы обойти проблему нужно в лямбде значение задавать как параметр с значением, поэтому вместо lambda: select_user(clid) нужно писать lambda clid=clid: select_user(clid) (т.е. мы объявили лямбду с параметром clid, у которого значение по-умолчанию берется из переменной clid)
Пример:
b = Button(tk, text = name, command=lambda clid=clid: select_user(clid))