2012-06-18 3 views
4

Я пытаюсь добавить несколько нумерованных команд в меню Tkinter, используя цикл for. При вызове команды его номер должен использоваться как аргумент функции команды. Следующий код не работает, потому что i вычисляется при вызове команды, которая после завершения цикла. Это означает, что аргумент, переданный функции1, всегда равен 15, тогда как я должен передать номер, который отображается на ярлыке команды. Есть ли способ сделать это?Как использовать переменную цикла в выражении лямбда

Примечание: Маркировка работает как задумано, производя 16 вариантов маркированы от 0 до 15

newMenu = Menu(menuButtonInstance) 
for i in range(16): 
    newMenu.add_command(label = '%s'%i, 
         command = lambda:function1(i)) 
menuButtonInstance.config(menu = newMenu) 

Заранее спасибо

ответ

4

один часто используемый способ обработки lambda «s позднего связывания, давая лямбда аргумент со значением по умолчанию установлено значение изменяющейся переменной:

newMenu.add_command(label='{0}'.format(i), 
         command=lambda x=i: function1(x)) 

Другая возможность заключается в использовании partial от functools:

newMenu.add_command(label='{0}'.format(i), 
         command=partial(function1, i)) 

(Обратите внимание, что PEP8 рекомендует не использовать пробелы на каждой стороне = при использовании ключевых аргументов. С другой стороны, вы должны положить пробелы вокруг всех операторов, как % в вашем примере)

+0

+1 для трюка лямбда-с-умолчанию-аргумента –

+0

Большое спасибо за хороший ответ – Petter

+1

Параметр 'partial' подход намного лучше ИМХО. По умолчанию аргумент аргумента - это изворотливый хак, который оставляет ошибочное впечатление, что аргумент по умолчанию предназначен для замены. –

Смежные вопросы