Python пропонує пакет importlib в якості частини стандартної бібліотеки модулів. Його завдання - забезпечити реалізацію оператора імпорту Python, а також функції __import __ (). На додаток, importlib дає програмісту можливість створити власний об'єкт (т.зв. імпортер), який може бути використаний для процесу імпорту.
Що щодо imp?
Існує ще один модуль, під назвою imp, який надає інтерфейс механізмам, які стоять за оператором Python import. Цей модуль вважається застарілим для Python 3.4. Передбачається, що importlib слід використовувати замість нього.
Цей модуль вельми складний у використанні, так що ми обмежимо наш кругозір, і зосередимося на наступних темах:
- динамічний імпорт
- Перевірка на можливість імпорту модуля
- Зручний сторонній модуль під назвою import_from_github_com
динамічний імпорт
Модуль importlib підтримує можливість імпорту модуля, який був переданий рядку. Так що давайте створимо кілька простих модулів, з якими ми зможемо працювати. Ми виділимо кожному модулю однаковий інтерфейс, але дамо їм виводити свої назви, щоб побачити різницю між ними. Створимо два модуля з різними назвами, на зразок foo.py і bar.py. і додамо в них наступний код:
Тут ми імпортуємо модуль importlib і створюємо дуже просту функцію під назвою dynamic_import. Все, що робить ця функція, це викликає іншу функцію importlib - import_module з рядком модуля, який ми їй передали, і повертає результат цього виклику. Далі, в нашому умовному операторі внизу, ми можемо викликати головний метод кожного модуля, який покірно виведе назву модуля. Ви, швидше за все, не будете робити це часто в своєму коді, але періодично вам може бути потрібно імпортувати модуль, коли він представлений тільки у вигляді рядка. Модуль importlib дає можливість зробити саме це.
Перевірка імпортованого модуля
Python містить стиль кодування під назвою EAFP: Easier to ask for forgiveness than permission (легше просити про прощення, ніж дозволу). Це означає, що найчастіше простіше припустити, що щось існує (наприклад, ключ в словнику), і зловити помилку, якщо це не так. Раніше ми намагалися імпортувати модуль, з ймовірністю отримати помилку ImportError. якщо його не існує. Що якщо нам потрібно перевірити і побачити, чи може модуль бути імпортованим, щоб виключити припущення? Ви можете домогтися цього з importlib!
print (dir (module))
Тут ми імпортуємо субмодуль з importlib під назвою util. У першій частині коду check_module міститься справжня магія, яку ми можемо побачити. У ній ми викликаємо функцію find_spec в рядку модуля, яка була передана раніше. Спочатку ми виконуємо передачу фейковий назви, потім ми робимо те ж, але до цього назвою модуля Python. Якщо ви запустите цей код, ви побачите, що коли ви передаєте назву невстановленого модуля, функція find_spec поверне None і наш код виведе повідомлення про те, що модуль не знайдено. Якщо він був знайдений, тоді ми повернемо специфікацію модуля. Ми можемо взяти цю специфікацію і використовувати її для імпорту модуля. Або ви можете просто передати рядок функції import_module. як ми робили в попередньому розділі. З цієї ж причини ми і розглянемо використання специфікації модуля в якості альтернативного способу. Погляньте на функцію import_module_from_spec в описаному вище коді. Вона приймає специфікацію модуля, яку повернула функція check_module. Далі ми передаємо її функції module_from_spec. яка повертає модуль import. У документації Python рекомендується запустити модуль після його імпорту, це ми і робимо за допомогою функції exec_module. Нарешті, ми отримаємо модуль і запустимо dir Python з ним, щоб переконатися в тому, що даний модуль такий, як ми очікували.
Імпорт з вихідного файлу
Субмодуль з importlib під назвою util може робити один трюк, який я хочу розглянути. Ви можете використовувати util для імпорту модуля, використовуючи тільки його шлях файлу і назва. Давайте розглянемо наступний приклад, щоб ви зрозуміли, що до чого: