Nano Hash - криптовалюты, майнинг, программирование

Команды кнопки Tkinter в цикле For

Я использую python 3 с tkinter, и у меня возникают проблемы с командой, которую я хочу выполнить с помощью кнопки. Генерируется переменное количество кнопок, по одной для каждого посетителя, и я пытаюсь вызвать функцию signOut нажатием кнопки, передавая ей соответствующий элемент (посетитель) из списка.

Я понимаю, что проблема связана с циклом for, поскольку к моменту нажатия кнопки i будет == последним элементом в списке. Как я могу сделать его конкретным для фактического посетителя. Кажется, я не могу придумать решение. Любые советы приветствуются.

buttonDictionary = {}
for i in range(0,len(currentVisitors)):
    buttonDictionary[i] = Button(bottomFrame, text=currentVisitors[i], command=lambda: signOut(topFrame, bottomFrame, currentVisitors[i]))
    buttonDictionary[i].pack()
26.08.2016

Ответы:


1

Насколько я понимаю, например. i в lambda в цикле, подобном этому, относится к самой переменной i, а не к значению переменной на каждой итерации, поэтому при вызове обратного вызова command он будет использовать значение i в этот момент, которое, как вы заметил значение на последней итерации.

Один из способов решить эту проблему — использовать файл partial. partial фактически "замораживает" аргументы в их текущем состоянии в цикле и использует их при вызове обратного вызова.

Попробуйте использовать partial вместо lambda вот так:

from functools import partial

buttonDictionary = {}
for i in range(0,len(currentVisitors)):
    buttonDictionary[i] = Button(bottomFrame, text=currentVisitors[i], command=partial(signOut, topFrame, bottomFrame, currentVisitors[i]))
    buttonDictionary[i].pack()

Другой способ, который я видел, но не пробовал, - это каждый раз назначать i новой переменной в вашем lambda:

command=lambda i=i: signOut(topFrame, bottomFrame, currentVisitors[i])

Я не раз обжегся, когда впервые начал работать с Python, используя лямбда-выражения в циклах (включая случай, очень похожий на этот, когда я пытался назначить обратный вызов для динамически генерируемых кнопок в цикле). Я даже создал фрагмент, который расширялся до think_about_it('are you sure you want to use a lambda?') всякий раз, когда я набирал lambda, просто чтобы напомнить себе о боли, которую я причинил себе этим...

26.08.2016
  • Это действительно решило проблему. Большое спасибо за ваш ответ! 27.08.2016
  • @ user3931640 Рад, что это сработало! Я обжигался этим несколько раз. Хуже всего, когда ты не замечаешь, что это происходит. Я постараюсь немного обновить свой ответ, объяснив, почему это происходит, или, по крайней мере, дать ссылку на кого-то, кто может это хорошо объяснить. 27.08.2016
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..