#python #list #tkinter #indexing #dynamic
Вопрос:
Я пытаюсь создать несколько 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 "Test2"
), но когда я нажимаю кнопки, они обе печатаются "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. это сработало для меня, но я заметил много странных вещей, подобных этому, с лямбдой. Есть ли причина, по которой лямбда вообще нужна?