Я хочу создать каскадное меню, которое создается динамически один раз, оно предназначено для создания нового окна на основе полученного аргумента.Однако кажется, что использование лямбда-функции с аргументом приводит к мягкому кодированию аргумента.Я хотел бы, чтобы оно оставалось жестко запрограммированным после создания меню.
См. Этот минимальный рабочий пример:
from tkinter import *
def print_number(num):
print(num)
root = Tk()
menubar = Menu(root)
cascade_menu = Menu(menubar, tearoff=0)
for ii in range(0, 5):
cascade_menu.add_command(label=str(ii), command=lambda: print_number(ii))
menubar.add_cascade(label="Number printer", menu=cascade_menu)
root.config(menu=menubar)
root.mainloop()
Это создает небольшое окно с одним каскадным меню, с записями 0,1,2,3,4.Я бы хотел нажать «0», чтобы на консоли было напечатано «0», то же самое для любого другого числа.Но поскольку ii
было оставлено определенным как 4, каждая команда будет просто печатать 4. Это si, потому что команда вызывается с переменной ii
, а не со значением, которое эта переменная имела, когда команда была назначена, что япредпочтительнее.
Есть ли обходной путь к этому?Я попытался объявить список лямбда-функций, но проблема остается.Я попытался использовать функцию eval
, но она также не решает проблему с реальной версией проблемы, так как, очевидно, мне нужно передать в качестве аргумента другую структуру, которая не обнаруживается при вызове eval.Альтернатива, которую я рассматриваю, - использовать скрипт для написания большого файла, который эффективно содержит объявления функций, таких как:
def print1():
print_number(1)
def print2():
print_number(2)
и так далее.Но это было бы очень хлопотно.
Я работаю с Python 3.7 в Windows.