Импортирование по имени в виде строки

importirovanie po imeni v vide stroki Экскурсия по tkinter, часть 1

Единственным хитроумным приемом в этом сценарии является использование встроенной функции __import__, импортирующей модуль по его имени в виде строки. Взглянем на следующие две строки из функции addComponents сценария:

module = __import__(demo) # импортировать по имени в виде строки

part = module.Demo(root) # прикрепить экземпляр, созданный его классом Demo

Они эквивалентны следующим строкам:

importdemoDlg

part = demoDlg’.Demo(root)

Однако последние две инструкции являются недопустимыми в языке Pythonимя модуля в инструкциях импорта должно быть идентификатором Python, а не строковым значением. Кроме того, имена модулей в инструкциях импорта интерпретируются буквально (то есть не вычисляются), и в точечной нотации идентификаторы должны выражать объект (а не строку с именем). Для обеспечения общности функция addComponents обходит список строк с именами и с помощью __import__ импортирует и возвращает модуль, идентифицируемый каждой строкой. Фактически действие цикла for эквивалентно следующим инструкциям:

import demoDlg, demoRadio, demoCheck, demoScale

part = demoDlg.Demo(root)

part = demoRadio.Demo(root)

part = demoCheck.Demo(root)

part = demoScale.Demo(root)

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

for demo in demoModules:

exec(‘from %s import Demo% demo) # сконструировать и выполнить from part = eval(‘Demo’)(root) # получить ссылку на импортированный

# объект по его имени в виде строки

Функция exec компилирует и выполняет строку с инструкцией Python (в данном случае from, загружающей класс Demo из модуля). Она действует, как если бы вместо вызова функции exec в исходный текст была вставлена строка с инструкцией. Следующий фрагмент позволяет добиться того же эффекта, но конструируя инструкцию import:

for demo in demoModules: exec(‘import %s% demo) # сконструировать и выполнить import part = eval(demo).Demo(root) # получить ссылку на объект модуля # также по имени в виде строки

Так как функции exec/eval поддерживают любые инструкции Python, этот прием оказывается более универсальным, чем использование функции __import__, но он может замедлять работу, потому что при этом требуется производить синтаксический анализ строк программного кода перед их выполнением.[XXXVI] Такое замедление может быть несущественным для графических интерфейсов — пользователи работают значительно медленнее, чем синтаксические анализаторы.

Использованная литература:
Марк Лутц — Программирование на Python, 4-е издание, I том, 2011

Оцените статью
Секреты программирования
Добавить комментарий