#python #tkinter #late-binding
#питон #tkinter
Вопрос:
Я пытаюсь создать несколько Button
s (с for
циклом), например:
def a(self, name): print(name) users = {"Test": "127.0.0.0", "Test2": "128.0.0.0"} row = 1 for name in users: user_button = Tkinter.Button(self.root, text=name, command=lambda: self.a(name)) user_button.grid(row=row, column=0) row = 1
и для каждой кнопки каждый получает свой собственный параметр (получение теста "Test"
и получение "Test2"
Теста2 ), но когда я нажимаю кнопки, они оба печатаются "Test2"
, что означает, что они используют одну и ту же функцию с одним и тем же параметром.
Как я могу решить эту проблему?
Ответ №1:
Проблема в том, что ваша ламба находится в цикле for. Ваш лямбда-индекс использует name
переменную, но name
переменная каждый раз переназначается через цикл for. Таким образом, в конце концов, все кнопки получают последнее значение, которое name
было присвоено в цикле for. Чтобы избежать этого, вы можете использовать параметры ключевых слов по умолчанию в выражении lamba, например так:
user_button = Tkinter.Button(self.root, text=name, command=lambda name=name: self.a(name))
Это привязывает текущее значение name
переменной к name
аргументу ключевого слова lamba каждый раз в цикле, производя желаемый эффект.
Комментарии:
1. Это не проблема tkinter, это проблема, касающаяся вложенности функций, замыканий и т. Д. Оно также существует в совершенно других контекстах. Тем не менее 1, так как в противном случае это точно описывает, что происходит.
2. @glglgl Вы на 100% правы. Не лучший выбор слов с моей стороны, пересмотрю.
3. Большое вам спасибо за этот ответ. Это спасло меня от еще нескольких часов поисков.
4. что делать, если мы хотим выполнить несколько функций? я. а и я. б
5. это сработало для меня, но я заметил много странных вещей, подобных этому, с лямбдой. Есть ли причина, по которой лямбда вообще нужна?