# `importlib` — Реалізація `import`

Added in version 3.1.

Вихідний код: Lib/importlib/__init__.py

## вступ

The purpose of the `importlib` package is three-fold.

One is to provide the implementation of the `import` statement (and thus, by extension, the `__import__()` function) in Python source code. This provides an implementation of `import` which is portable to any Python interpreter. This also provides an implementation which is easier to comprehend than one implemented in a programming language other than Python.

По-друге, компоненти для реалізації `import` представлені в цьому пакунку, що полегшує користувачам створення власних користувацьких об’єктів (відомих загалом як importer) для участі в процесі імпорту.

Three, the package contains modules exposing additional functionality for managing aspects of Python packages:

- `importlib.metadata` presents access to metadata from third-party distributions.

- `importlib.resources` provides routines for accessing non-code «resources» from Python packages.

Дивись також

Оператор import

  Посилання на мову для оператора `import`.

Специфікація пакетів

  Оригінальна специфікація пакетів. Деяка семантика змінилася з моменту написання цього документа (наприклад, переспрямування на основі `None` у `sys.modules`).

Функція `__import__()`

  Оператор `import` є синтаксичним цукром для цієї функції.

The initialization of the sys.path module search path

  The initialization of `sys.path`.

PEP 235

  Імпорт на платформи без урахування регістру

PEP 263

  Визначення кодувань вихідного коду Python

PEP 302

  Нові гачки імпорту

PEP 328

  Імпорт: багаторядковий і абсолютний/відносний

PEP 366

  Явний відносний імпорт головного модуля

PEP 420

  Неявні пакети простору імен

PEP 451

  Тип ModuleSpec для системи імпорту

PEP 488

  Видалення файлів PYO

PEP 489

  Багатофазна ініціалізація модуля розширення

PEP 552

  Детерміновані фото

PEP 3120

  Використання UTF-8 як вихідного кодування за умовчанням

PEP 3147

  Каталоги репозиторіїв PYC

## Функції

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)

  Реалізація вбудованої функції `__import__()`.

  Примітка

  Програмне імпортування модулів має використовувати `import_module()` замість цієї функції.

importlib.import_module(name, package=None)

  Імпортувати модуль. Аргумент name визначає, який модуль імпортувати в абсолютних чи відносних значеннях (наприклад, `pkg.mod` або `..mod`). Якщо ім’я вказано у відносних термінах, тоді в аргументі package має бути встановлено ім’я пакета, який має діяти як прив’язка для визначення імені пакета (наприклад, `import_module('..mod', 'pkg' .subpkg')` імпортує `pkg.mod`).

  Функція `import_module()` діє як спрощена оболонка навколо `importlib.__import__()`. Це означає, що вся семантика функції походить від `importlib.__import__()`. Найважливіша відмінність між цими двома функціями полягає в тому, що `import_module()` повертає вказаний пакунок або модуль (наприклад, `pkg.mod`), а `__import__()` повертає пакунок або модуль верхнього рівня (напр. `пакет`).

  Якщо ви динамічно імпортуєте модуль, який було створено після того, як інтерпретатор почав виконання (наприклад, створив вихідний файл Python), вам може знадобитися викликати `invalidate_caches()`, щоб система імпорту помітила новий модуль.

  Змінено в версії 3.3: Батьківські пакети імпортуються автоматично.

importlib.invalidate_caches()

  Визнати недійсними внутрішні кеші засобів пошуку, які зберігаються в `sys.meta_path`. Якщо засіб пошуку реалізує `invalidate_caches()`, тоді він буде викликаний для виконання недійсності. Цю функцію слід викликати, якщо будь-які модулі створюються/встановлюються під час роботи вашої програми, щоб гарантувати, що всі шукачі помітять існування нового модуля.

  Added in version 3.3.

  Змінено в версії 3.10: Namespace packages created/installed in a different `sys.path` location after the same namespace was already imported are noticed.

importlib.reload(module)

  Перезавантажте раніше імпортований модуль. Аргумент має бути об’єктом модуля, тому він має бути успішно імпортований раніше. Це корисно, якщо ви відредагували вихідний файл модуля за допомогою зовнішнього редактора і хочете випробувати нову версію, не виходячи з інтерпретатора Python. Поверненим значенням є об’єкт модуля (який може бути іншим, якщо повторне імпортування спричиняє розміщення іншого об’єкта в `sys.modules`).

  Коли `reload()` виконується:

  - Код модуля Python перекомпілюється, а код рівня модуля повторно виконується, визначаючи новий набір об’єктів, які прив’язуються до імен у словнику модуля шляхом повторного використання loader, який початково завантажив модуль. Функція `init` модулів розширення не викликається вдруге.

  - Як і у випадку з усіма іншими об’єктами в Python, старі об’єкти відновлюються лише після того, як їх кількість посилань зменшується до нуля.

  - Імена в просторі імен модуля оновлюються, щоб вказувати на будь-які нові або змінені об’єкти.

  - Інші посилання на старі об’єкти (наприклад, імена, зовнішні по відношенню до модуля) не повертаються до нових об’єктів і повинні бути оновлені в кожному просторі імен, де вони зустрічаються, якщо це потрібно.

  Існує ряд інших застережень:

  Коли модуль перезавантажується, його словник (що містить глобальні змінні модуля) зберігається. Перевизначення імен замінить старі визначення, тому це, як правило, не проблема. Якщо нова версія модуля не визначає назву, яка була визначена старою версією, старе визначення залишається. Цю функцію можна використовувати на користь модуля, якщо він підтримує глобальну таблицю або кеш об’єктів — за допомогою оператора `try` він може перевірити наявність таблиці та за бажанням пропустити її ініціалізацію:

      try:
          cache
      except NameError:
          cache = {}

  Зазвичай не дуже корисно перезавантажувати вбудовані або динамічно завантажувані модулі. Перезавантажувати `sys`, `__main__`, `builtins` та інші ключові модулі не рекомендується. У багатьох випадках модулі розширення не призначені для ініціалізації більше одного разу, і можуть виникати будь-які збої під час перезавантаження.

  Якщо модуль імпортує об’єкти з іншого модуля за допомогою `from` … `import` …, виклик `reload()` для іншого модуля не перевизначає об’єкти, імпортовані з нього — один із способів обійти це — повторно виконати оператор `from`, інший — використати замість нього `import` і кваліфіковані імена (module.name).

  Якщо модуль створює екземпляри класу, перезавантаження модуля, який визначає клас, не впливає на визначення методів екземплярів — вони продовжують використовувати старе визначення класу. Те саме стосується похідних класів.

  Added in version 3.4.

  Змінено в версії 3.7: `ModuleNotFoundError` виникає, коли модуль, який перезавантажується, не має `ModuleSpec`.

## `importlib.abc` – Абстрактні базові класи, пов’язані з імпортом

Вихідний код: Lib/importlib/abc.py

Модуль `importlib.abc` містить усі основні абстрактні базові класи, які використовуються `import`. Деякі підкласи основних абстрактних базових класів також надаються для допомоги в реалізації основних ABC.

Ієрархія ABC:

    object
     +-- MetaPathFinder
     +-- PathEntryFinder
     +-- Loader
          +-- ResourceLoader --------+
          +-- InspectLoader          |
               +-- ExecutionLoader --+
                                     +-- FileLoader
                                     +-- SourceLoader

class importlib.abc.MetaPathFinder

  Абстрактний базовий клас, що представляє meta path finder.

  Added in version 3.3.

  Змінено в версії 3.10: No longer a subclass of `Finder`.

  find_spec(fullname, path, target=None)

    An abstract method for finding a spec for the specified module. If this is a top-level import, path will be `None`. Otherwise, this is a search for a subpackage or module and path will be the value of `__path__` from the parent package. If a spec cannot be found, `None` is returned. When passed in, `target` is a module object that the finder may use to make a more educated guess about what spec to return. `importlib.util.spec_from_loader()` may be useful for implementing concrete `MetaPathFinders`.

    Added in version 3.4.

  invalidate_caches()

    Додатковий метод, який під час виклику має зробити недійсним будь-який внутрішній кеш, який використовує шукач. Використовується `importlib.invalidate_caches()` під час визнання недійсними кешів усіх засобів пошуку на `sys.meta_path`.

    Змінено в версії 3.4: Returns `None` when called instead of `NotImplemented`.

class importlib.abc.PathEntryFinder

  Абстрактний базовий клас, що представляє path entry finder. Хоча він має певну схожість із `MetaPathFinder`, `PathEntryFinder` призначений для використання лише в підсистемі імпорту на основі шляху, яку надає `importlib.machinery.PathFinder`.

  Added in version 3.3.

  Змінено в версії 3.10: No longer a subclass of `Finder`.

  find_spec(fullname, target=None)

    Абстрактний метод для пошуку spec для вказаного модуля. Шукач шукатиме модуль лише в межах path entry, якому він призначений. Якщо специфікацію неможливо знайти, повертається `None`. Коли передано, `target` є об’єктом модуля, який шукач може використовувати, щоб зробити більш освічене припущення про те, яку специфікацію потрібно повернути. `importlib.util.spec_from_loader()` може бути корисним для реалізації конкретних `PathEntryFinders`.

    Added in version 3.4.

  invalidate_caches()

    Додатковий метод, який під час виклику має зробити недійсним будь-який внутрішній кеш, який використовує шукач. Використовується `importlib.machinery.PathFinder.invalidate_caches()` під час визнання недійсними кешів усіх кешованих засобів пошуку.

class importlib.abc.Loader

  Абстрактний базовий клас для loader. Перегляньте PEP 302 для точного визначення завантажувача.

  Loaders that wish to support resource reading should implement a `get_resource_reader()` method as specified by `importlib.resources.abc.ResourceReader`.

  Змінено в версії 3.7: Introduced the optional `get_resource_reader()` method.

  create_module(spec)

    Метод, який повертає об’єкт модуля для використання під час імпорту модуля. Цей метод може повертати `None`, вказуючи, що семантика створення модуля за замовчуванням має мати місце.

    Added in version 3.4.

    Змінено в версії 3.6: This method is no longer optional when `exec_module()` is defined.

  exec_module(module)

    An abstract method that executes the module in its own namespace when a module is imported or reloaded. The module should already be initialized when `exec_module()` is called. When this method exists, `create_module()` must be defined.

    Added in version 3.4.

    Змінено в версії 3.6: `create_module()` must also be defined.

  load_module(fullname)

    A legacy method for loading a module. If the module cannot be loaded, `ImportError` is raised, otherwise the loaded module is returned.

    If the requested module already exists in `sys.modules`, that module should be used and reloaded. Otherwise the loader should create a new module and insert it into `sys.modules` before any loading begins, to prevent recursion from the import. If the loader inserted a module and the load fails, it must be removed by the loader from `sys.modules`; modules already in `sys.modules` before the loader began execution should be left alone.

    The loader should set several attributes on the module (note that some of these attributes can change when a module is reloaded):

    - `module.__name__`

    - `module.__file__`

    - `module.__cached__` (deprecated)

    - `module.__path__`

    - `module.__package__` (deprecated)

    - `module.__loader__` (deprecated)

    Коли `exec_module()` доступний, тоді надається функція зворотної сумісності.

    Змінено в версії 3.4: Raise `ImportError` when called instead of `NotImplementedError`. Functionality provided when `exec_module()` is available.

    Застаріло починаючи з версії 3.4: The recommended API for loading a module is `exec_module()` (and `create_module()`). Loaders should implement it instead of `load_module()`. The import machinery takes care of all the other responsibilities of `load_module()` when `exec_module()` is implemented.

class importlib.abc.ResourceLoader

  Абстрактний базовий клас для loader, який реалізує необов’язковий протокол PEP 302 для завантаження довільних ресурсів із внутрішнього сховища.

  Застаріло починаючи з версії 3.7: This ABC is deprecated in favour of supporting resource loading through `importlib.resources.abc.ResourceReader`.

  abstractmethod get_data(path)

    An abstract method to return the bytes for the data located at path. Loaders that have a file-like storage back-end that allows storing arbitrary data can implement this abstract method to give direct access to the data stored. `OSError` is to be raised if the path cannot be found. The path is expected to be constructed using a module’s `__file__` attribute or an item from a package’s `__path__`.

    Змінено в версії 3.4: Викликає `OSError` замість `NotImplementedError`.

class importlib.abc.InspectLoader

  Абстрактний базовий клас для loader, який реалізує додатковий протокол PEP 302 для завантажувачів, які перевіряють модулі.

  get_code(fullname)

    Повертає об’єкт коду для модуля або `None`, якщо модуль не має об’єкта коду (як, наприклад, у випадку вбудованого модуля). Викликати `ImportError`, якщо завантажувач не може знайти запитуваний модуль.

    Примітка

    Хоча метод має реалізацію за замовчуванням, пропонується замінити його, якщо це можливо для продуктивності.

    Змінено в версії 3.4: Більше не абстрактне, а конкретна реалізація.

  abstractmethod get_source(fullname)

    Абстрактний метод для повернення вихідного коду модуля. Він повертається як текстовий рядок з використанням universal newlines, переводячи всі розпізнані роздільники рядків у символи `'\n'`. Повертає `None`, якщо джерело недоступне (наприклад, вбудований модуль). Викликає `ImportError`, якщо завантажувач не може знайти вказаний модуль.

    Змінено в версії 3.4: Викликає `ImportError` замість `NotImplementedError`.

  is_package(fullname)

    Додатковий метод для повернення істинного значення, якщо модуль є пакетом, і хибного значення в іншому випадку. `ImportError` виникає, якщо loader не може знайти модуль.

    Змінено в версії 3.4: Викликає `ImportError` замість `NotImplementedError`.

  static source_to_code(data, path='<string>')

    Створіть об’єкт коду з джерела Python.

    Аргументом data може бути те, що підтримує функція `compile()` (тобто рядок або байти). Аргумент path має бути «шляхом», звідки походить вихідний код, що може бути абстрактним поняттям (наприклад, розташуванням у файлі zip).

    З наступним об’єктом коду можна виконати його в модулі, запустивши `exec(code, module.__dict__)`.

    Added in version 3.4.

    Змінено в версії 3.5: Зробив метод статичним.

  exec_module(module)

    Реалізація `Loader.exec_module()`.

    Added in version 3.4.

  load_module(fullname)

    Реалізація `Loader.load_module()`.

    Застаріло починаючи з версії 3.4: замість цього використовуйте `exec_module()`.

class importlib.abc.ExecutionLoader

  Абстрактний базовий клас, успадкований від `InspectLoader`, який, реалізований, допомагає модулю виконуватися як сценарій. ABC представляє необов’язковий протокол PEP 302.

  abstractmethod get_filename(fullname)

    An abstract method that is to return the value of `__file__` for the specified module. If no path is available, `ImportError` is raised.

    Якщо вихідний код доступний, тоді метод має повертати шлях до вихідного файлу, незалежно від того, чи використовувався байт-код для завантаження модуля.

    Змінено в версії 3.4: Викликає `ImportError` замість `NotImplementedError`.

class importlib.abc.FileLoader(fullname, path)

  Абстрактний базовий клас, який успадковує `ResourceLoader` і `ExecutionLoader`, надаючи конкретні реалізації `ResourceLoader.get_data()` і `ExecutionLoader.get_filename()`.

  Аргумент повне ім’я — це повністю визначене ім’я модуля, який має обробляти завантажувач. Аргумент path — це шлях до файлу модуля.

  Added in version 3.3.

  name

    Назва модуля, який може обробляти завантажувач.

  path

    Шлях до файлу модуля.

  load_module(fullname)

    Викликає `load_module()` супер.

    Застаріло починаючи з версії 3.4: Натомість використовуйте `Loader.exec_module()`.

  abstractmethod get_filename(fullname)

    Повертає `path`.

  abstractmethod get_data(path)

    Читає шлях як двійковий файл і повертає байти з нього.

class importlib.abc.SourceLoader

  Абстрактний базовий клас для реалізації вихідного (і необов’язково байт-коду) завантаження файлу. Клас успадковує як `ResourceLoader`, так і `ExecutionLoader`, що вимагає реалізації:

  - `ResourceLoader.get_data()`

  - `ExecutionLoader.get_filename()`

      Має повертати лише шлях до вихідного файлу; завантаження без джерел не підтримується.

  Абстрактні методи, визначені цим класом, призначені для додавання додаткової підтримки файлу байт-коду. Нереалізація цих додаткових методів (або виклик їх `NotImplementedError`) змушує завантажувач працювати лише з вихідним кодом. Реалізація методів дозволяє завантажувачу працювати з вихідними та файлами байт-коду; він не допускає безджерельного завантаження, де надається лише байт-код. Файли байт-коду є оптимізацією для прискорення завантаження шляхом видалення кроку синтаксичного аналізу компілятора Python, тому API, специфічний для байт-коду, не розкривається.

  path_stats(path)

    Додатковий абстрактний метод, який повертає `dict`, що містить метадані про вказаний шлях. Підтримувані ключі словника:

    - `'mtime'` (обов’язковий): ціле число або число з плаваючою комою, що представляє час модифікації вихідного коду;

    - `'size'` (необов’язковий): розмір у байтах вихідного коду.

    Будь-які інші ключі в словнику ігноруються, щоб дозволити майбутні розширення. Якщо шлях не можна обробити, виникає `OSError`.

    Added in version 3.3.

    Змінено в версії 3.4: Викликати `OSError` замість `NotImplementedError`.

  path_mtime(path)

    Додатковий абстрактний метод, який повертає час модифікації для вказаного шляху.

    Застаріло починаючи з версії 3.3: Цей метод застарів на користь `path_stats()`. Вам не потрібно його впроваджувати, але він все ще доступний для цілей сумісності. Викликати `OSError`, якщо шлях неможливо обробити.

    Змінено в версії 3.4: Викликати `OSError` замість `NotImplementedError`.

  set_data(path, data)

    Додатковий абстрактний метод, який записує вказані байти в шлях до файлу. Будь-які проміжні каталоги, яких не існує, створюються автоматично.

    When writing to the path fails because the path is read-only (`errno.EACCES`/`PermissionError`), do not propagate the exception.

    Змінено в версії 3.4: Більше не викликає `NotImplementedError` під час виклику.

  get_code(fullname)

    Конкретна реалізація `InspectLoader.get_code()`.

  exec_module(module)

    Конкретна реалізація `Loader.exec_module()`.

    Added in version 3.4.

  load_module(fullname)

    Конкретна реалізація `Loader.load_module()`.

    Застаріло починаючи з версії 3.4: Замість цього використовуйте `exec_module()`.

  get_source(fullname)

    Конкретна реалізація `InspectLoader.get_source()`.

  is_package(fullname)

    Конкретна реалізація `InspectLoader.is_package()`. Модуль вважається пакетом, якщо його шлях до файлу (як надано `ExecutionLoader.get_filename()`) є файлом з назвою `__init__`, коли розширення файлу видалено і сама назва модуля не закінчується на `__init__`.

class importlib.abc.ResourceReader

  Замінено TraversableResources

  abstract base class для надання можливості читати ресурси.

  From the perspective of this ABC, a resource is a binary artifact that is shipped within a package. Typically this is something like a data file that lives next to the `__init__.py` file of the package. The purpose of this class is to help abstract out the accessing of such data files so that it does not matter if the package and its data file(s) are stored e.g. in a zip file versus on the file system.

  Для будь-якого методу цього класу очікується, що аргумент resource буде path-like object, який концептуально представляє лише ім’я файлу. Це означає, що шляхи підкаталогів не повинні включатися в аргумент resource. Це пояснюється тим, що місце розташування пакета, для якого призначений зчитувач, діє як «каталог». Тому метафорою для каталогів і імен файлів є пакети та ресурси відповідно. Ось чому очікується, що екземпляри цього класу безпосередньо співвідносяться з певним пакетом (замість того, щоб потенційно представляти кілька пакетів або модуль).

  Очікується, що завантажувачі, які бажають підтримувати читання ресурсів, нададуть метод під назвою `get_resource_reader(fullname)`, який повертає об’єкт, що реалізує цей інтерфейс ABC. Якщо модуль, указаний повним іменем, не є пакетом, цей метод має повернути `None`. Об’єкт, сумісний із цим ABC, слід повертати лише тоді, коли вказаний модуль є пакетом.

  Added in version 3.7.

  Deprecated since version 3.12, removed in version 3.14: Use `importlib.resources.abc.TraversableResources` instead.

  abstractmethod open_resource(resource)

    Повертає відкритий file-like object для двійкового читання ресурсу.

    Якщо ресурс не знайдено, виникає `FileNotFoundError`.

  abstractmethod resource_path(resource)

    Повертає шлях файлової системи до ресурсу.

    Якщо ресурс конкретно не існує у файловій системі, викликайте `FileNotFoundError`.

  abstractmethod is_resource(name)

    Повертає `True`, якщо назване ім’я вважається ресурсом. `FileNotFoundError` виникає, якщо name не існує.

  abstractmethod contents()

    Повертає iterable рядків над вмістом пакета. Зауважте, що не обов’язково, щоб усі імена, які повертає ітератор, були фактичними ресурсами, наприклад. прийнятно повертати імена, для яких `is_resource()` буде false.

    Дозволити повертати нересурсні імена, щоб дозволити ситуації, коли те, як пакет і його ресурси зберігаються, відомі апріорі, і нересурсні імена будуть корисними. Наприклад, дозволено повертати імена підкаталогів, щоб, якщо відомо, що пакет і ресурси зберігаються у файловій системі, ці імена підкаталогів можна було використовувати безпосередньо.

    Абстрактний метод повертає ітерацію без елементів.

class importlib.abc.Traversable

  An object with a subset of `pathlib.Path` methods suitable for traversing directories and opening files.

  For a representation of the object on the file-system, use `importlib.resources.as_file()`.

  Added in version 3.9.

  Deprecated since version 3.12, removed in version 3.14: Use `importlib.resources.abc.Traversable` instead.

  name

    Abstract. The base name of this object without any parent references.

  abstractmethod iterdir()

    Yield `Traversable` objects in `self`.

  abstractmethod is_dir()

    Return `True` if `self` is a directory.

  abstractmethod is_file()

    Return `True` if `self` is a file.

  abstractmethod joinpath(child)

    Return Traversable child in `self`.

  abstractmethod __truediv__(child)

    Return `Traversable` child in `self`.

  abstractmethod open(mode='r', *args, **kwargs)

    mode може бути «r» або «rb», щоб відкрити як текстовий або двійковий файл. Повертає дескриптор, придатний для читання (те саме, що `pathlib.Path.open`).

    Коли відкривається як текст, приймає параметри кодування, такі як ті, які приймає `io.TextIOWrapper`.

  read_bytes()

    Read contents of `self` as bytes.

  read_text(encoding=None)

    Read contents of `self` as text.

class importlib.abc.TraversableResources

  An abstract base class for resource readers capable of serving the `importlib.resources.files()` interface. Subclasses `importlib.resources.abc.ResourceReader` and provides concrete implementations of the `importlib.resources.abc.ResourceReader`’s abstract methods. Therefore, any loader supplying `importlib.abc.TraversableResources` also supplies ResourceReader.

  Очікується, що завантажувачі, які бажають підтримувати читання ресурсів, реалізують цей інтерфейс.

  Added in version 3.9.

  Deprecated since version 3.12, removed in version 3.14: Use `importlib.resources.abc.TraversableResources` instead.

  abstractmethod files()

    Returns a `importlib.resources.abc.Traversable` object for the loaded package.

## `importlib.machinery` – Імпортери та перехоплювачі шляху

Вихідний код: Lib/importlib/machinery.py

Цей модуль містить різноманітні об’єкти, які допомагають `import` знаходити та завантажувати модулі.

importlib.machinery.SOURCE_SUFFIXES

  Список рядків, що представляють розпізнані суфікси файлів для вихідних модулів.

  Added in version 3.3.

importlib.machinery.DEBUG_BYTECODE_SUFFIXES

  Список рядків, що представляють суфікси файлів для неоптимізованих модулів байт-коду.

  Added in version 3.3.

  Застаріло починаючи з версії 3.5: Натомість використовуйте `BYTECODE_SUFFIXES`.

importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES

  Список рядків, що представляють суфікси файлів для оптимізованих модулів байт-коду.

  Added in version 3.3.

  Застаріло починаючи з версії 3.5: Натомість використовуйте `BYTECODE_SUFFIXES`.

importlib.machinery.BYTECODE_SUFFIXES

  Список рядків, що представляють розпізнані суфікси файлів для модулів байт-коду (включно з початковою крапкою).

  Added in version 3.3.

  Змінено в версії 3.5: Значення більше не залежить від `__debug__`.

importlib.machinery.EXTENSION_SUFFIXES

  Список рядків, що представляють розпізнані суфікси файлів для модулів розширення.

  Added in version 3.3.

importlib.machinery.all_suffixes()

  Повертає комбінований список рядків, що представляють усі суфікси файлів для модулів, розпізнаних стандартним механізмом імпорту. Це допоміжний засіб для коду, якому просто потрібно знати, чи шлях до файлової системи потенційно посилається на модуль, не потребуючи жодних деталей щодо типу модуля (наприклад, `inspect.getmodulename()`).

  Added in version 3.3.

class importlib.machinery.BuiltinImporter

  importer для вбудованих модулів. Усі відомі вбудовані модулі перераховані в `sys.builtin_module_names`. Цей клас реалізує ABC `importlib.abc.MetaPathFinder` і `importlib.abc.InspectLoader`.

  У цьому класі визначені лише методи класу, щоб полегшити потребу в створенні екземплярів.

  Змінено в версії 3.5: Як частина PEP 489, вбудований імпортер тепер реалізує `Loader.create_module()` і `Loader.exec_module()`

class importlib.machinery.FrozenImporter

  importer для заморожених модулів. Цей клас реалізує ABC `importlib.abc.MetaPathFinder` і `importlib.abc.InspectLoader`.

  У цьому класі визначені лише методи класу, щоб полегшити потребу в створенні екземплярів.

  Змінено в версії 3.4: Отримано методи `create_module()` і `exec_module()`.

class importlib.machinery.WindowsRegistryFinder

  Finder для модулів, оголошених у реєстрі Windows. Цей клас реалізує `importlib.abc.MetaPathFinder` ABC.

  У цьому класі визначені лише методи класу, щоб полегшити потребу в створенні екземплярів.

  Added in version 3.3.

  Застаріло починаючи з версії 3.6: Натомість використовуйте конфігурацію `site`. Майбутні версії Python можуть не вмикати цей засіб пошуку за замовчуванням.

class importlib.machinery.PathFinder

  A Finder для атрибутів `sys.path` і пакета `__path__`. Цей клас реалізує `importlib.abc.MetaPathFinder` ABC.

  У цьому класі визначені лише методи класу, щоб полегшити потребу в створенні екземплярів.

  classmethod find_spec(fullname, path=None, target=None)

    Метод класу, який намагається знайти spec для модуля, указаного повним ім’ям у `sys.path` або, якщо визначено, у path. Для кожного запису шляху, який шукається, перевіряється `sys.path_importer_cache`. Якщо знайдено нефальшивий об’єкт, він використовується як path entry finder для пошуку модуля, який шукається. Якщо в `sys.path_importer_cache` не знайдено жодного запису, тоді `sys.path_hooks` шукає засіб пошуку для запису шляху та, якщо знайдено, зберігається в `sys.path_importer_cache` із запитанням про модуль. Якщо жоден шукач не знайдено, тоді `None` зберігається в кеші та повертається.

    Added in version 3.4.

    Змінено в версії 3.5: Якщо поточний робочий каталог, представлений порожнім рядком, більше не дійсний, тоді повертається `None`, але жодне значення не кешується в `sys.path_importer_cache`.

  classmethod invalidate_caches()

    Викликає `importlib.abc.PathEntryFinder.invalidate_caches()` для всіх засобів пошуку, збережених у `sys.path_importer_cache`, які визначають метод. Інакше записи в `sys.path_importer_cache`, для яких встановлено значення `None`, видаляються.

    Змінено в версії 3.7: Записи `None` у `sys.path_importer_cache` видаляються.

  Змінено в версії 3.4: Викликає об’єкти в `sys.path_hooks` з поточним робочим каталогом для `''` (тобто порожній рядок).

class importlib.machinery.FileFinder(path, *loader_details)

  Конкретна реалізація `importlib.abc.PathEntryFinder`, яка кешує результати з файлової системи.

  Аргумент шлях — це каталог, пошук якого відповідає за пошук.

  Аргумент loader_details — це змінна кількість кортежів із 2 елементів, кожен із яких містить завантажувач і послідовність суфіксів файлів, які розпізнає завантажувач. Очікується, що завантажувачі будуть викликаними, які приймають два аргументи імені модуля та шляху до знайденого файлу.

  Засіб пошуку кешуватиме вміст каталогу за потреби, виконуючи stat виклики для кожного пошуку модуля, щоб переконатися, що кеш не застарів. Оскільки нестабільність кешу залежить від деталізації інформації про стан операційної системи файлової системи, існує потенційна конкуренція щодо пошуку модуля, створення нового файлу, а потім пошуку модуля, який представляє новий файл. Якщо операції відбуваються досить швидко, щоб відповідати деталізації викликів stat, пошук модулів не вдасться. Щоб цього не сталося, під час динамічного створення модуля обов’язково викликайте `importlib.invalidate_caches()`.

  Added in version 3.3.

  path

    Шлях, за яким шукач шукатиме.

  find_spec(fullname, target=None)

    Спробуйте знайти специфікацію для обробки повного імені в `path`.

    Added in version 3.4.

  invalidate_caches()

    Очистіть внутрішній кеш.

  classmethod path_hook(*loader_details)

    A class method which returns a closure for use on `sys.path_hooks`. An instance of `FileFinder` is returned by the closure using the path argument given to the closure directly and loader_details indirectly.

    Якщо аргумент закриття не є існуючим каталогом, виникає `ImportError`.

class importlib.machinery.SourceFileLoader(fullname, path)

  Конкретна реалізація `importlib.abc.SourceLoader` шляхом створення підкласу `importlib.abc.FileLoader` і надання деяких конкретних реалізацій інших методів.

  Added in version 3.3.

  name

    Назва модуля, який оброблятиме цей завантажувач.

  path

    Шлях до вихідного файлу.

  is_package(fullname)

    Повертає `True`, якщо `path` є для пакета.

  path_stats(path)

    Конкретна реалізація `importlib.abc.SourceLoader.path_stats()`.

  set_data(path, data)

    Конкретна реалізація `importlib.abc.SourceLoader.set_data()`.

  load_module(name=None)

    Конкретна реалізація `importlib.abc.Loader.load_module()`, де вказувати назву модуля для завантаження необов’язково.

    Застаріло починаючи з версії 3.6: Замість цього використовуйте `importlib.abc.Loader.exec_module()`.

class importlib.machinery.SourcelessFileLoader(fullname, path)

  Конкретна реалізація `importlib.abc.FileLoader`, яка може імпортувати файли байт-коду (тобто файлів вихідного коду не існує).

  Зауважте, що пряме використання файлів байт-коду (а отже, не файлів вихідного коду) перешкоджає використанню ваших модулів усіма реалізаціями Python або новими версіями Python, які змінюють формат байт-коду.

  Added in version 3.3.

  name

    Назва модуля, який оброблятиме завантажувач.

  path

    Шлях до файлу байт-коду.

  is_package(fullname)

    Визначає, чи є модуль пакетом на основі `path`.

  get_code(fullname)

    Повертає об’єкт коду для `name`, створеного з `path`.

  get_source(fullname)

    Повертає `None`, оскільки файли байт-коду не мають джерела, коли використовується цей завантажувач.

  load_module(name=None)

  Конкретна реалізація `importlib.abc.Loader.load_module()`, де вказувати назву модуля для завантаження необов’язково.

  Застаріло починаючи з версії 3.6: Замість цього використовуйте `importlib.abc.Loader.exec_module()`.

class importlib.machinery.ExtensionFileLoader(fullname, path)

  Конкретна реалізація `importlib.abc.ExecutionLoader` для модулів розширення.

  Аргумент fullname вказує назву модуля, який має підтримувати завантажувач. Аргумент path — це шлях до файлу модуля розширення.

  Note that, by default, importing an extension module will fail in subinterpreters if it doesn’t implement multi-phase init (see PEP 489), even if it would otherwise import successfully.

  Added in version 3.3.

  Змінено в версії 3.12: Multi-phase init is now required for use in subinterpreters.

  name

    Назва модуля, який підтримує завантажувач.

  path

    Шлях до модуля розширення.

  create_module(spec)

    Створює об’єкт модуля з заданої специфікації відповідно до PEP 489.

    Added in version 3.5.

  exec_module(module)

    Ініціалізує вказаний об’єкт модуля відповідно до PEP 489.

    Added in version 3.5.

  is_package(fullname)

    Повертає `True`, якщо шлях до файлу вказує на модуль `__init__` пакета на основі `EXTENSION_SUFFIXES`.

  get_code(fullname)

    Повертає `None`, оскільки модулі розширення не мають об’єкта коду.

  get_source(fullname)

    Повертає `None`, оскільки модулі розширення не мають вихідного коду.

  get_filename(fullname)

    Повертає `path`.

    Added in version 3.4.

class importlib.machinery.NamespaceLoader(name, path, path_finder)

  A concrete implementation of `importlib.abc.InspectLoader` for namespace packages. This is an alias for a private class and is only made public for introspecting the `__loader__` attribute on namespace packages:

      >>> from importlib.machinery import NamespaceLoader
      >>> import my_namespace
      >>> isinstance(my_namespace.__loader__, NamespaceLoader)
      True
      >>> import importlib.abc
      >>> isinstance(my_namespace.__loader__, importlib.abc.Loader)
      True

  Added in version 3.11.

class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)

  A specification for a module’s import-system-related state. This is typically exposed as the module’s `__spec__` attribute. Many of these attributes are also available directly on a module: for example, `module.__spec__.origin == module.__file__`. Note, however, that while the values are usually equivalent, they can differ since there is no synchronization between the two objects. For example, it is possible to update the module’s `__file__` at runtime and this will not be automatically reflected in the module’s `__spec__.origin`, and vice versa.

  Added in version 3.4.

  name

    The module’s fully qualified name (see `module.__name__`). The finder should always set this attribute to a non-empty string.

  loader

    The loader used to load the module (see `module.__loader__`). The finder should always set this attribute.

  origin

    The location the loader should use to load the module (see `module.__file__`). For example, for modules loaded from a `.py` file this is the filename. The finder should always set this attribute to a meaningful value for the loader to use. In the uncommon case that there is not one (like for namespace packages), it should be set to `None`.

  submodule_search_locations

    A (possibly empty) sequence of strings enumerating the locations in which a package’s submodules will be found (see `module.__path__`). Most of the time there will only be a single directory in this list.

    The finder should set this attribute to a sequence, even an empty one, to indicate to the import system that the module is a package. It should be set to `None` for non-package modules. It is set automatically later to a special object for namespace packages.

  loader_state

    The finder may set this attribute to an object containing additional, module-specific data to use when loading the module. Otherwise it should be set to `None`.

  cached

    The filename of a compiled version of the module’s code (see `module.__cached__`). The finder should always set this attribute but it may be `None` for modules that do not need compiled code stored.

  parent

    (Read-only) The fully qualified name of the package the module is in (or the empty string for a top-level module). See `module.__package__`. If the module is a package then this is the same as `name`.

  has_location

    `True` if the spec’s `origin` refers to a loadable location, `False` otherwise. This value impacts how `origin` is interpreted and how the module’s `__file__` is populated.

class importlib.machinery.AppleFrameworkLoader(name, path)

  A specialization of `importlib.machinery.ExtensionFileLoader` that is able to load extension modules in Framework format.

  For compatibility with the iOS App Store, all binary modules in an iOS app must be dynamic libraries, contained in a framework with appropriate metadata, stored in the `Frameworks` folder of the packaged app. There can be only a single binary per framework, and there can be no executable binary material outside the Frameworks folder.

  To accommodate this requirement, when running on iOS, extension module binaries are not packaged as `.so` files on `sys.path`, but as individual standalone frameworks. To discover those frameworks, this loader is be registered against the `.fwork` file extension, with a `.fwork` file acting as a placeholder in the original location of the binary on `sys.path`. The `.fwork` file contains the path of the actual binary in the `Frameworks` folder, relative to the app bundle. To allow for resolving a framework-packaged binary back to the original location, the framework is expected to contain a `.origin` file that contains the location of the `.fwork` file, relative to the app bundle.

  For example, consider the case of an import `from foo.bar import _whiz`, where `_whiz` is implemented with the binary module `sources/foo/bar/_whiz.abi3.so`, with `sources` being the location registered on `sys.path`, relative to the application bundle. This module must be distributed as `Frameworks/foo.bar._whiz.framework/foo.bar._whiz` (creating the framework name from the full import path of the module), with an `Info.plist` file in the `.framework` directory identifying the binary as a framework. The `foo.bar._whiz` module would be represented in the original location with a `sources/foo/bar/_whiz.abi3.fwork` marker file, containing the path `Frameworks/foo.bar._whiz/foo.bar._whiz`. The framework would also contain `Frameworks/foo.bar._whiz.framework/foo.bar._whiz.origin`, containing the path to the `.fwork` file.

  When a module is loaded with this loader, the `__file__` for the module will report as the location of the `.fwork` file. This allows code to use the `__file__` of a module as an anchor for file system traversal. However, the spec origin will reference the location of the actual binary in the `.framework` folder.

  The Xcode project building the app is responsible for converting any `.so` files from wherever they exist in the `PYTHONPATH` into frameworks in the `Frameworks` folder (including stripping extensions from the module file, the addition of framework metadata, and signing the resulting framework), and creating the `.fwork` and `.origin` files. This will usually be done with a build step in the Xcode project; see the iOS documentation for details on how to construct this build step.

  Added in version 3.13.

  Availability: iOS.

  name

    Назва модуля, який підтримує завантажувач.

  path

    Path to the `.fwork` file for the extension module.

## `importlib.util` – Код утиліти для імпортерів

Вихідний код: Lib/importlib/util.py

Цей модуль містить різні об’єкти, які допомагають у створенні importer.

importlib.util.MAGIC_NUMBER

  Байти, які представляють номер версії байт-коду. Якщо вам потрібна допомога із завантаженням/записом байт-коду, скористайтеся `importlib.abc.SourceLoader`.

  Added in version 3.4.

importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)

  Поверніть шлях PEP 3147/PEP 488 до скомпільованого файлу, пов’язаного з вихідним шляхом. Наприклад, якщо path є `/foo/bar/baz.py`, значення, що повертається, буде `/foo/bar/__pycache__/baz.cpython-32.pyc` для Python 3.2. Рядок `cpython-32` походить від поточного магічного тегу (див. `get_tag()`; якщо `sys.implementation.cache_tag` не визначено, тоді буде викликана `NotImplementedError`).

  Параметр optimization використовується для визначення рівня оптимізації файлу байт-коду. Порожній рядок не означає оптимізації, тому `/foo/bar/baz.py` з оптимізацією `''` призведе до шляху байт-коду `/foo/bar/__pycache__/baz. cpython-32.pyc`. `None` спричиняє використання рівня оптимізації інтерпретатора. Використовується будь-яке інше представлення рядка значення, тому `/foo/bar/baz.py` з оптимізацією `2` призведе до шляху байт-коду `/foo/bar/__pycache__/baz. cpython-32.opt-2.pyc`. Рядкове представлення оптимізації може бути лише буквено-цифровим, інакше виникає `ValueError`.

  Параметр debug_override є застарілим і може використовуватися для заміни системного значення для `__debug__`. Значення `True` є еквівалентом налаштування optimization для порожнього рядка. Значення `False` те саме, що встановити optimization на `1`. Якщо debug_override і оптимізація не мають значення `None`, тоді виникає `TypeError`.

  Added in version 3.4.

  Змінено в версії 3.5: Параметр optimization було додано, а параметр debug_override визнано застарілим.

  Змінено в версії 3.6: Приймає path-like object.

importlib.util.source_from_cache(path)

  Враховуючи шлях до імені файлу PEP 3147, поверніть пов’язаний шлях до файлу вихідного коду. Наприклад, якщо шлях є `/foo/bar/__pycache__/baz.cpython-32.pyc`, повернутий шлях буде `/foo/bar/baz.py`. path не обов’язково існує, однак якщо він не відповідає формату PEP 3147 або PEP 488, виникає помилка `ValueError`. Якщо `sys.implementation.cache_tag` не визначено, виникає `NotImplementedError`.

  Added in version 3.4.

  Змінено в версії 3.6: Приймає path-like object.

importlib.util.decode_source(source_bytes)

  Декодуйте задані байти, що представляють вихідний код, і поверніть його як рядок із універсальними символами нового рядка (як вимагає `importlib.abc.InspectLoader.get_source()`).

  Added in version 3.4.

importlib.util.resolve_name(name, package)

  Розділіть відносну назву модуля на абсолютну.

  Якщо ім’я не має початкових крапок, то ім’я просто повертається. Це дозволяє використовувати таке як `importlib.util.resolve_name('sys', __spec__.parent)` без виконання перевірки, щоб побачити, чи потрібен аргумент package.

  `ImportError` is raised if name is a relative module name but package is a false value (e.g. `None` or the empty string). `ImportError` is also raised if a relative name would escape its containing package (e.g. requesting `..bacon` from within the `spam` package).

  Added in version 3.3.

  Змінено в версії 3.9: Щоб покращити узгодженість із операторами імпорту, підніміть `ImportError` замість `ValueError` для недійсних відносних спроб імпорту.

importlib.util.find_spec(name, package=None)

  Find the spec for a module, optionally relative to the specified package name. If the module is in `sys.modules`, then `sys.modules[name].__spec__` is returned (unless the spec would be `None` or is not set, in which case `ValueError` is raised). Otherwise a search using `sys.meta_path` is done. `None` is returned if no spec is found.

  Якщо назва призначена для підмодуля (містить крапку), батьківський модуль імпортується автоматично.

  name і package працюють так само, як і для `import_module()`.

  Added in version 3.4.

  Змінено в версії 3.7: Raises `ModuleNotFoundError` instead of `AttributeError` if package is in fact not a package (i.e. lacks a `__path__` attribute).

importlib.util.module_from_spec(spec)

  Створіть новий модуль на основі spec і `spec.loader.create_module`.

  Якщо `spec.loader.create_module` не повертає `None`, тоді будь-які раніше існуючі атрибути не будуть скинуті. Крім того, помилка `AttributeError` не буде викликана, якщо вона буде активована під час доступу до spec або встановлення атрибута в модулі.

  Цій функції краще використовувати `types.ModuleType` для створення нового модуля, оскільки spec використовується для встановлення якомога більшої кількості керованих імпортом атрибутів для модуля.

  Added in version 3.5.

importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)

  Фабрична функція для створення екземпляра `ModuleSpec` на основі завантажувача. Параметри мають таке ж значення, як і для ModuleSpec. Функція використовує доступні API loader, такі як `InspectLoader.is_package()`, щоб заповнити будь-яку відсутню інформацію в специфікації.

  Added in version 3.4.

importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)

  Фабрична функція для створення екземпляра `ModuleSpec` на основі шляху до файлу. Відсутню інформацію буде заповнено в специфікації за допомогою API завантажувача та через те, що модуль буде заснований на файлі.

  Added in version 3.4.

  Змінено в версії 3.6: Приймає path-like object.

importlib.util.source_hash(source_bytes)

  Повертає хеш source_bytes як байти. Файл `.pyc` на основі хешу вставляє `source_hash()` вмісту відповідного вихідного файлу у свій заголовок.

  Added in version 3.7.

importlib.util._incompatible_extension_module_restrictions(*, disable_check)

  A context manager that can temporarily skip the compatibility check for extension modules. By default the check is enabled and will fail when a single-phase init module is imported in a subinterpreter. It will also fail for a multi-phase init module that doesn’t explicitly support a per-interpreter GIL, when imported in an interpreter with its own GIL.

  Note that this function is meant to accommodate an unusual case; one which is likely to eventually go away. There’s is a pretty good chance this is not what you were looking for.

  You can get the same effect as this function by implementing the basic interface of multi-phase init (PEP 489) and lying about support for multiple interpreters (or per-interpreter GIL).

  Попередження

  Using this function to disable the check can lead to unexpected behavior and even crashes. It should only be used during extension module development.

  Added in version 3.12.

class importlib.util.LazyLoader(loader)

  Клас, який відкладає виконання завантажувача модуля, поки модуль не отримає доступ до атрибута.

  This class only works with loaders that define `exec_module()` as control over what module type is used for the module is required. For those same reasons, the loader’s `create_module()` method must return `None` or a type for which its `__class__` attribute can be mutated along with not using slots. Finally, modules which substitute the object placed into `sys.modules` will not work as there is no way to properly replace the module references throughout the interpreter safely; `ValueError` is raised if such a substitution is detected.

  Примітка

  Для проектів, де час запуску є критичним, цей клас дозволяє потенційно мінімізувати вартість завантаження модуля, якщо він ніколи не використовується. Для проектів, де час запуску не є суттєвим, використання цього класу суворо не рекомендується через те, що повідомлення про помилки, створені під час завантаження, відкладаються та, таким чином, виникають поза контекстом.

  Added in version 3.5.

  Змінено в версії 3.6: Почався виклик `create_module()`, видаляючи попередження про сумісність для `importlib.machinery.BuiltinImporter` і `importlib.machinery.ExtensionFileLoader`.

  classmethod factory(loader)

    A class method which returns a callable that creates a lazy loader. This is meant to be used in situations where the loader is passed by class instead of by instance.

        suffixes = importlib.machinery.SOURCE_SUFFIXES
        loader = importlib.machinery.SourceFileLoader
        lazy_loader = importlib.util.LazyLoader.factory(loader)
        finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))

## Приклади

### Програмний імпорт

Щоб програмно імпортувати модуль, використовуйте `importlib.import_module()`.

    import importlib

    itertools = importlib.import_module('itertools')

### Перевірка можливості імпорту модуля

Якщо вам потрібно з’ясувати, чи можна імпортувати модуль без фактичного імпортування, тоді вам слід скористатися `importlib.util.find_spec()`.

Зауважте, що якщо `name` є підмодулем (містить крапку), `importlib.util.find_spec()` імпортує батьківський модуль.

    import importlib.util
    import sys

    # For illustrative purposes.
    name = 'itertools'

    if name in sys.modules:
        print(f"{name!r} already in sys.modules")
    elif (spec := importlib.util.find_spec(name)) is not None:
        # If you chose to perform the actual import ...
        module = importlib.util.module_from_spec(spec)
        sys.modules[name] = module
        spec.loader.exec_module(module)
        print(f"{name!r} has been imported")
    else:
        print(f"can't find the {name!r} module")

### Пряме імпортування вихідного файлу

This recipe should be used with caution: it is an approximation of an import statement where the file path is specified directly, rather than `sys.path` being searched. Alternatives should first be considered first, such as modifying `sys.path` when a proper module is required, or using `runpy.run_path()` when the global namespace resulting from running a Python file is appropriate.

To import a Python source file directly from a path, use the following recipe:

    import importlib.util
    import sys

    def import_from_path(module_name, file_path):
        spec = importlib.util.spec_from_file_location(module_name, file_path)
        module = importlib.util.module_from_spec(spec)
        sys.modules[module_name] = module
        spec.loader.exec_module(module)
        return module

    # For illustrative purposes only (use of `json` is arbitrary).
    import json
    file_path = json.__file__
    module_name = json.__name__

    # Similar outcome as `import json`.
    json = import_from_path(module_name, file_path)

### Реалізація відкладеного імпорту

У прикладі нижче показано, як реалізувати відкладений імпорт:

    >>> import importlib.util
    >>> import sys
    >>> def lazy_import(name):
    ...     spec = importlib.util.find_spec(name)
    ...     loader = importlib.util.LazyLoader(spec.loader)
    ...     spec.loader = loader
    ...     module = importlib.util.module_from_spec(spec)
    ...     sys.modules[name] = module
    ...     loader.exec_module(module)
    ...     return module
    ...
    >>> lazy_typing = lazy_import("typing")
    >>> #lazy_typing is a real module object,
    >>> #but it is not loaded in memory yet.
    >>> lazy_typing.TYPE_CHECKING
    False

### Налаштування імпортера

For deep customizations of import, you typically want to implement an importer. This means managing both the finder and loader side of things. For finders there are two flavours to choose from depending on your needs: a meta path finder or a path entry finder. The former is what you would put on `sys.meta_path` while the latter is what you create using a path entry hook on `sys.path_hooks` which works with `sys.path` entries to potentially create a finder. This example will show you how to register your own importers so that import will use them (for creating an importer for yourself, read the documentation for the appropriate classes defined within this package):

    import importlib.machinery
    import sys

    # For illustrative purposes only.
    SpamMetaPathFinder = importlib.machinery.PathFinder
    SpamPathEntryFinder = importlib.machinery.FileFinder
    loader_details = (importlib.machinery.SourceFileLoader,
                      importlib.machinery.SOURCE_SUFFIXES)

    # Setting up a meta path finder.
    # Make sure to put the finder in the proper location in the list in terms of
    # priority.
    sys.meta_path.append(SpamMetaPathFinder)

    # Setting up a path entry finder.
    # Make sure to put the path hook in the proper location in the list in terms
    # of priority.
    sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))

### Наближення `importlib.import_module()`

Import itself is implemented in Python code, making it possible to expose most of the import machinery through importlib. The following helps illustrate the various APIs that importlib exposes by providing an approximate implementation of `importlib.import_module()`:

    import importlib.util
    import sys

    def import_module(name, package=None):
        """An approximate implementation of import."""
        absolute_name = importlib.util.resolve_name(name, package)
        try:
            return sys.modules[absolute_name]
        except KeyError:
            pass

        path = None
        if '.' in absolute_name:
            parent_name, _, child_name = absolute_name.rpartition('.')
            parent_module = import_module(parent_name)
            path = parent_module.__spec__.submodule_search_locations
        for finder in sys.meta_path:
            spec = finder.find_spec(absolute_name, path)
            if spec is not None:
                break
        else:
            msg = f'No module named {absolute_name!r}'
            raise ModuleNotFoundError(msg, name=absolute_name)
        module = importlib.util.module_from_spec(spec)
        sys.modules[absolute_name] = module
        spec.loader.exec_module(module)
        if path is not None:
            setattr(parent_module, child_name, module)
        return module