Проблема не в вашем синтаксисе; это то, что вы пытаетесь сделать что-то незаконное. Вы не можете создавать новые локальные переменные с exec
. (Причина того, что тот же код за пределами функции работает, заключается в том, что в целом вы можете создать новую глобальную переменную с exec
, но это все еще плохая идея.)
Но вам также не нужно , чтобы сделать это. В Python все является объектом, включая классы. Итак, вам просто нужно получить класс из имени. Затем вы можете создать экземпляр этого класса и сохранить его в локальной переменной, просто используя тот же обычный синтаксис, который вы использовали бы для статического создания экземпляра класса и сохранения его в локальной переменной.
Правильный способ сделать это - сохранить словарь, отображающий имена для объектов классов. Если вы хотите стать умным, вы можете написать декоратор, который регистрирует классы в этом словаре, но если для вас это звучит как греческий, просто сделайте это явно:
classes = {'Spam': Spam, 'Eggs': Eggs}
Если у вас есть десятки из них, вы можете избежать повторения с таким пониманием:
classes = {cls.__name__: cls for cls in ('Spam', 'Eggs')}
… но в этот момент вам, вероятно, лучше научиться писать декоратор.
В любом случае, вы можете заполнить поле со списком клавишами этого словаря, а не повторять себя в строке combo['values']
.
А затем, чтобы создать экземпляр, вы просто делаете это:
cls = classes[comboExample.get()]
instance = cls()
(Очевидно, вы можете свернуть это в одну строку, но я подумал, что было бы легче понять, если бы мы разделили две части.)
Если вы действительно хотите сделать это хакерским способом, вы можете. Каждый класс, созданный вами в этом модуле, уже хранится в словаре по имени - глобальном пространстве имен модуля. Это то же самое место, где вы пытались найти его неявно с помощью exec
, но вы можете найти его явно, просто просмотрев его в globals()
. Однако в глобальном пространстве имен также есть имена всех ваших функций, импортированных модулей, констант и переменных верхнего уровня и т. Д., Поэтому обычно это плохая идея. (Очевидно, что exec
имеет точно такие же проблемы.)