importlib — Реализация import

Добавлено в версии 3.1.


Знакомство

Пакет importlib предназначен для двух целей. Одна из них — реализация оператора import (и функции __import__()) в исходном коде Python. Он реализует переносимый на любой интерпретатор Python import. Данную реализацию легче понять, чем отличную от языка программирования Python реализацию.

Во-вторых, в пакете представлены компоненты для реализации import, что упрощает пользователям создание собственных настраиваемых объектов (известных как импортеры) для управления процессом импорта.

См.также

Оператор import
Справочник по языку для оператора import.
Спецификация пакетов
Оригинальная спецификация пакетов. С тех пор некоторая семантика изменилась с момента написания данного документа (например, перенаправление на основе None в sys.modules).
Функция __import__()
Оператор import является синтаксическим сахаром для функции.
PEP 235
Импорт на платформах без учета регистра
PEP 263
Определение кодировок исходного кода Python
PEP 302
Новые хуки импорта
PEP 328
Импорт: многострочный и абсолютный/относительный
PEP 366
Явный/относительный импорт от главного модуля
PEP 420
Неявные пакеты пространства имён
PEP 451
Тип ModuleSpec для системы импорта
PEP 488
Удаление PYO файлов
PEP 489
Многоэтапная инициализация модуля расширения
PEP 552
Детерминированные пики (pycs)
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__() возвращает пакет или модуль верхнего уровня (например, pkg).

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

Изменено в версии 3.3: Родительские пакеты импортируются автоматически.

importlib.find_loader(name, path=None)

Ищет загрузчик для модуля, возможно, в пределах указанного path. Если модуль находится в sys.modules, то возвращается sys.modules[name].__loader__ (если только загрузчик не будет None или не установлен, и в этом случае вызывается ValueError). В противном случае выполняется поиск с использованием sys.meta_path. Возвращается None, если загрузчик не найден.

Имя с точками не имеет неявно импортированных родителей, т. к. это требует их загрузки, а это может быть нежелательно. Чтобы правильно импортировать подмодуль, вам нужно импортировать все родительские пакеты подмодуля и использовать правильный аргумент path.

Добавлено в версии 3.3.

Изменено в версии 3.4: Если __loader__ не задан, вызывается ValueError, как если бы для атрибута было задано значение None.

Не рекомендуется, начиная с версии 3.4: Вместо него используйте importlib.util.find_spec().

importlib.invalidate_caches()

Делает недействительными внутренние кеши поисковиков, хранящихся по адресу sys.meta_path. Если поисковик реализует invalidate_caches(), то она будет вызвана для выполнения аннулирования. Функцию следует вызывать, если какие-либо модули создаются/устанавливаются во время работы вашей программы, для гарантии, что все поисковики заметят существование нового модуля.

Добавлено в версии 3.3.

importlib.reload(module)

Перезагружает ранее импортированный файл module. Аргумент должен быть объектом модуля, поэтому он должен успешно импортироваться ранее. Она полезна, если вы редактировали исходный файл модуля с помощью внешнего редактора и хотите попробовать новую версию, не выходя из интерпретатора Python. Возвращаемое значение — это объект модуля (который может отличаться, если повторный импорт приводит к размещению другого объекта в sys.modules).

При выполнении reload():

  • Код модуля Python перекомпилируется, а код уровня модуля повторно выполняется, определяя новое множество объектов, связанные с именами в словаре модуля, путём повторного использования загрузчика, который первоначально загрузил модуль. Функция init модулей расширения не вызывается второй раз.
  • Как и в случае со всеми другими объектами в Python, старые объекты восстанавливаются только после того, как количество их ссылок упадет до нуля.
  • Имена в пространстве имён модулей обновляются, чтобы указывать на любые новые или измененные объекты.
  • Другие ссылки на старые объекты (например, внешние по отношению к модулю имена) не привязываются к новым объектам и должны быть обновлены в каждом пространстве имён, где они встречаются, если это желательно.

Есть ряд других предостережений:

Когда модуль перезагружается, его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределение имён перекрывает старые определения, так что обычно это не проблема. Если новая версия модуля не определяет имя, которое было определено в старой версии, остаётся старое определение. Данную функцию можно использовать с пользой для модуля, если он поддерживает глобальную таблицу или кэш объектов — с оператором try, который он может проверить на наличие таблицы и при желании пропустить её инициализацию:

try:
    cache
except NameError:
    cache = {}

Обычно не очень полезно перезагружать встроенные или динамически загружаемые модули. Не рекомендуется перезагружать sys, __main__, builtins и другие ключевые модули. Во многих случаях модули расширения не предназначены для инициализации более одного раза и могут произвольно дать сбой при перезагрузке.

Если модуль импортирует объекты из другого модуля, используя fromimport …, вызов reload() для другого модуля не переопределяет объекты, импортированные из него. Один из способов обойти это — повторно выполнить оператор from, другой — использовать import и квалифицированные имена (module.name) вместо него.

Если модуль создаёт экземпляры класса, перезагрузка определяющего класс модуля, не влияет на определения методов экземпляров, — они продолжают использовать старое определение класса. То же самое верно и для производных классов.

Добавлено в версии 3.4.

Изменено в версии 3.7: Вызывается ModuleNotFoundError, когда в перезагружаемом модуле отсутствует ModuleSpec.

importlib.abc — Абстрактные базовые классы, связанные с импортом


Модуль importlib.abc содержит все основные абстрактные базовые классы, используемые import. Некоторые подклассы основных абстрактных базовых классов также предоставляются для помощи в реализации основных ABC.

Иерархия АВС:

object
 +-- Finder (deprecated)
 |    +-- MetaPathFinder
 |    +-- PathEntryFinder
 +-- Loader
      +-- ResourceLoader --------+
      +-- InspectLoader          |
           +-- ExecutionLoader --+
                                 +-- FileLoader
                                 +-- SourceLoader
class importlib.abc.Finder

Абстрактный базовый класс, представляющий поисковик.

Не рекомендуется, начиная с версии 3.3: Вместо него используйте MetaPathFinder или PathEntryFinder.

abstractmethod find_module(fullname, path=None)

Абстрактный метод поиска загрузчика для указанного модуля. Первоначально указанный в PEP 302, данный метод предназначался для использования в sys.meta_path и в подсистеме импорта на основе пути.

Изменено в версии 3.4: Возвращает None при вызове вместо NotImplementedError.

class importlib.abc.MetaPathFinder

Абстрактный базовый класс, представляющий поисковик мета-пути. Для совместимости это подкласс Finder.

Добавлено в версии 3.3.

find_spec(fullname, path, target=None)

Абстрактный метод поиска спецификации для указанного модуля. Если импорт верхнего уровня, path будет None. В противном случае поиск подпакета или модуля и path будет значением __path__ из родительского пакета. Если спецификацию не удается найти, возвращается None. При передаче target является объектом модуля, который поисковик может использовать, чтобы сделать более обоснованное предположение о том, какую спецификацию возвращать. importlib.util.spec_from_loader() может пригодиться для реализации MetaPathFinders.

Добавлено в версии 3.4.

find_module(fullname, path)

Устаревший метод поиска загрузчика для указанного модуля. Если это импорт верхнего уровня, path будет None. В противном случае это поиск подпакета или модуля и path будет значением __path__ из родительского пакета. Если загрузчик не найден, возвращается None.

Если find_spec() определён, обеспечивается функциональность обратной совместимости.

Изменено в версии 3.4: Возвращает None при вызове вместо NotImplementedError. Может использовать find_spec() для обеспечения функциональности.

Не рекомендуется, начиная с версии 3.4: Вместо нее используйте find_spec().

invalidate_caches()

Необязательный метод, аннулирующий при вызове любой внутренний кеш, используемый поисковиком. Используется importlib.invalidate_caches() при аннулировании кешей всех поисковиков на sys.meta_path.

Изменено в версии 3.4: Возвращает None при вызове вместо NotImplemented.

class importlib.abc.PathEntryFinder

Абстрактный базовый класс, представляющий поисковик пути. Хотя у него есть некоторое сходство с MetaPathFinder, PathEntryFinder предназначен для использования только в подсистеме импорта на основе пути, предоставляемой PathFinder. Данный ABC является подклассом Finder только из соображений совместимости.

Добавлено в версии 3.3.

find_spec(fullname, target=None)

Абстрактный метод поиска спецификации для указанного модуля. Поисковик будет искать модуль только в пути входа, которому он назначен. Если спецификацию не удается найти, возвращается None. При передаче target является объектом модуля, который поисковик может использовать, чтобы сделать более обоснованное предположение о том, какую спецификацию возвращать. importlib.util.spec_from_loader() может пригодиться для реализации PathEntryFinders.

Добавлено в версии 3.4.

find_loader(fullname)

Устаревший метод поиска загрузчика для указанного модуля. Возвращает кортеж из двух строк (loader, portion), где portion — это последовательность местоположений в файловой системе, составляющих часть пакета пространства имён. Загрузчик может быть None при указании portion, чтобы обозначить вклад местоположений файловой системы в пакет пространства имён. Пустой список можно использовать для portion, чтобы указать, что загрузчик не является частью пакета пространства имён. Если loaderNone, а portion — это пустой список, то загрузчик или место для пакета пространства имён не найдено (т. е. не удалось найти что-либо для модуля).

Если find_spec() определён, обеспечивается функциональность обратной совместимости.

Изменено в версии 3.4: Возвращает (None, []) вместо NotImplementedError. Если доступно, использует find_spec() для обеспечения функциональности.

Не рекомендуется, начиная с версии 3.4: Вместо него используйте find_spec().

find_module(fullname)

Реализация Finder.find_module(), которая эквивалентна self.find_loader(fullname)[0].

Не рекомендуется, начиная с версии 3.4: Вместо него используйте find_spec().

invalidate_caches()

Необязательный метод, аннулирующий при вызове любой внутренний кеш, используемый поисковиком. Используется PathFinder.invalidate_caches() при аннулировании кешей всех кешированных поисковиков.

class importlib.abc.Loader

Абстрактный базовый класс для загрузчика. См. PEP 302 для точного определения загрузчика.

Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать метод get_resource_reader(fullname), как указано в importlib.abc.ResourceReader.

Изменено в версии 3.7: Введен необязательный метод get_resource_reader().

create_module(spec)

Возвращает объект модуля для использования при импорте модуля. Данный метод может возвращать None, указывая на то, что должна выполняться семантика создания модуля по умолчанию.

Добавлено в версии 3.4.

Изменено в версии 3.5: Начиная с Python 3.6, данный метод не будет необязательным при определении exec_module().

exec_module(module)

Абстрактный метод, выполняющий модуль в его собственном пространстве имён, когда модуль импортируется или перезагружается. Модуль уже должен инициализирован при вызове exec_module(). Если данный метод существует, необходимо определить create_module().

Добавлено в версии 3.4.

Изменено в версии 3.6: create_module() также должен быть определён.

load_module(fullname)

Устаревший метод загрузки модуля. Если модуль не может быть загружен, вызывается ImportError, иначе возвращается загруженный модуль.

Если запрошенный модуль уже существует в sys.modules, данный модуль следует использовать и перезагрузить. В противном случае загрузчик должен создает новый модуль и вставить его в sys.modules до начала загрузки, чтобы предотвратить рекурсию импорта. Если загрузчик вставил модуль и загрузка не удалась, он должен удаляться загрузчиком из sys.modules; модули, находящиеся в sys.modules до начала выполнения загрузчика, следует оставить в покое (см. importlib.util.module_for_loader()).

Загрузчик должен установить несколько атрибутов модуля. (Обратите внимание, что некоторые из данных атрибутов могут измениться при перезагрузке модуля):

  • __name__
    Имя модуля.
  • __file__
    Путь к месту хранения данных модуля (не задается для встроенных модулей).
  • __cached__
    Путь к месту, где хранится/должна храниться скомпилированная версия модуля (не устанавливается, если атрибут не подходит).
  • __path__
    Список строк, определяющих путь поиска в пакете. Данный атрибут не установлен для модулей.
  • __package__
    Полное имя пакета, под которым модуль был загружен как подмодуль (или пустая строка для модулей верхнего уровня). Для пакетов это то же самое, что и __name__. Декоратор importlib.util.module_for_loader() может обрабатывать детали для __package__.
  • __loader__
    Загрузчик, используемый для загрузки модуля. Декоратор importlib.util.module_for_loader() может обрабатывать детали для __package__.

Когда exec_module() доступен, обеспечивается функциональность обратной совместимости.

Изменено в версии 3.4: Вызывается ImportError при вызове вместо NotImplementedError. Функциональность предоставляется при наличии exec_module().

Не рекомендуется, начиная с версии 3.4: Рекомендуемый API для загрузки модуля — exec_module()create_module()). Загрузчики должны реализовать его вместо load_module(). Механизм импорта берет на себя все остальные функции load_module() при реализации exec_module().

module_repr(module)

Устаревший метод, при реализации вычисляет и возвращает repr данного модуля в виде строки. Тип модуля по умолчанию repr() будет использовать результат метода соответствующим образом.

Добавлено в версии 3.3.

Изменено в версии 3.4: Сделано необязательным вместо абстрактного метода.

Не рекомендуется, начиная с версии 3.4: Механизм импорта теперь позаботится об этом автоматически.

class importlib.abc.ResourceReader

Абстрактный базовый класс, для обеспечения возможности чтения resource.

С точки зрения данного ABC, resource — это двоичный артефакт, поставляемый в пакете. Обычно это что-то вроде файла данных, который находится рядом с файлом __init__.py пакета. Цель этого класса — помочь абстрагироваться от доступа к таким файлам данных, чтобы не имело значения, хранятся ли пакет и его файл(ы) данных, например, в zip по сравнению с файловой системой.

Для любого из методов класса ожидается, что аргумент resource будет путеподобным объектом, который концептуально представляет просто имя файла. Это означает, что в аргумент resource не следует включать пути к подкаталогам. Это связано с тем, что расположение пакета, для которого предназначено средство чтения, действует как «каталог». Следовательно, метафора имён каталогов и файлов — пакеты и ресурсы соответственно. По этой же причине ожидается, что экземпляры класса напрямую соотносятся с пакетом (вместо потенциального представления нескольких пакетов или модуля).

Ожидается, что поддерживающие чтение ресурсов загрузчики, предоставят метод с именем get_resource_reader(fullname), который возвращает объект, реализующий данный ABC интерфейс. Если указанный полным именем модуль, не является пакетом, данный метод должен вернуть None. Должен возвращаться совместимый с ABC объект только тогда, когда указанный модуль является пакетом.

Добавлено в версии 3.7.

abstractmethod open_resource(resource)

Возвращает открытый файлоподобный объект для двоичного чтения resource.

Если ресурс не может быть найден, вызывается FileNotFoundError.

abstractmethod resource_path(resource)

Возвращает путь файловой системы к resource.

Если ресурс не существует в файловой системе, вызывается FileNotFoundError.

abstractmethod is_resource(name)

Возвращает True, если именованный name считается ресурсом. FileNotFoundError вызывается, если name не существует.

abstractmethod contents()

Возвращает итератор строк по содержимому пакета. Обратите внимание, что не требуется, чтобы возвращаемые итератором все имена, были фактическими ресурсами, например, допустимо возвращать имена, для которых is_resource() будет ложным.

Разрешение возвращать имена, не относящиеся к ресурсам, предназначено для ситуаций, когда способ хранения пакета и его ресурсов известен априори, и имена, не относящиеся к ресурсам, были бы полезны. Например, разрешено возвращать имена подкаталогов, поэтому, когда известно, что пакет и ресурсы хранятся в файловой системе, данные имена подкаталогов можно использовать напрямую.

Абстрактный метод возвращает итератор без элементов.

class importlib.abc.ResourceLoader

Абстрактный базовый класс для загрузчика, реализующий необязательный протокол PEP 302 для загрузки произвольных ресурсов из внутреннего хранилища.

Не рекомендуется, начиная с версии 3.7: Данный ABC устарел в пользу поддержки загрузки ресурсов через importlib.abc.ResourceReader.

abstractmethod get_data(path)

Абстрактный метод для возвращения байтов данных, расположенных по адресу path. У загрузчиков, которые имеют файловую серверную часть хранилища, позволяющая хранить произвольные данные, могут реализовать данный абстрактный метод, чтобы предоставить прямой доступ к сохраненным данным. Должно вызываться OSError, если path не найден. Ожидается, что path будет создан с использованием атрибута модуля __file__ или элемента из __path__ пакета.

Изменено в версии 3.4: Вызывает OSError вместо NotImplementedError.

class importlib.abc.InspectLoader

Абстрактный базовый класс для загрузчика, реализующий необязательный протокол PEP 302 для проверяющих модули загрузчиков.

get_code(fullname)

Возвращает объект кода для модуля или None, если у модуля нет объекта кода (как в случае, например, для встроенного модуля). Вызывается ImportError, если загрузчик не может найти запрошенный модуль.

Примечание

Хотя у данного метода есть реализация по умолчанию, предлагается переопределить её, если это возможно, для повышения производительности.

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

abstractmethod get_source(fullname)

Абстрактный метод для возвращения источника модуля. Он возвращается в виде текстовой строки с использованием универсального символа новой строки, переводя все распознанные разделители строк в символы '\n'. Возвращает None, если источник недоступен (например, встроенный модуль). Вызывает ImportError, если загрузчик не может найти указанный модуль.

Изменено в версии 3.4: Вызывает ImportError вместо NotImplementedError.

is_package(fullname)

Абстрактный метод, возвращающий истинное значение, если модуль является пакетом, и ложное значение в противном случае. Вызывается ImportError, если загрузчик не может найти модуль.

Изменено в версии 3.4: Вызывает ImportError вместо NotImplementedError.

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

Создаёт объект кода из исходного кода Python.

Аргумент data может быть тем, что поддерживает функция compile() (т. е. строкой или байтами). Аргумент path должен быть «путём» к источнику исходного кода, который может быть абстрактным понятием (например, расположение в zip-файле).

С последующим кодовым объектом его можно выполнить в модуле, запустив exec(code, module.__dict__).

Добавлено в версии 3.4.

Изменено в версии 3.5: Сделал метод статическим.

exec_module(module)

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

Добавлено в версии 3.4.

load_module(fullname)

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

Не рекомендуется, начиная с версии 3.4: Вместо него используйте exec_module().

class importlib.abc.ExecutionLoader

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

abstractmethod get_filename(fullname)

Абстрактный метод, возвращающий значение __file__ для указанного модуля. Если путь недоступен, вызывается ImportError.

Если исходный код доступен, то метод должен возвращать путь к исходному файлу, независимо от того, использовался ли байт-код для загрузки модуля.

Изменено в версии 3.4: Вызывает ImportError вместо NotImplementedError.

class importlib.abc.FileLoader(fullname, path)

Абстрактный базовый класс, наследуемый от ResourceLoader и ExecutionLoader, предоставляя реализации ResourceLoader.get_data() и ExecutionLoader.get_filename().

Аргумент fullname — это полностью разрешенное имя модуля, обрабатываемое загрузчиком. Аргумент path — это путь к файлу модуля.

Добавлено в версии 3.3.

name

Имя модуля, который может обрабатывать загрузчик.

path

Путь к файлу модуля.

load_module(fullname)

Вызов super load_module().

Не рекомендуется, начиная с версии 3.4: Вместо него используйте Loader.exec_module().

abstractmethod get_filename(fullname)

Возвращает path.

abstractmethod get_data(path)

Читает path как двоичный файл и возвращает из него байты.

class importlib.abc.SourceLoader

Абстрактный базовый класс для реализации загрузки файла исходного кода (и, возможно, байт-кода). Класс наследуется как от ResourceLoader, так и от ExecutionLoader, что требует реализации:

Определённые этим классом абстрактные методы, предназначены для добавления дополнительной поддержки файлов байт-кода. Если не реализовать данные необязательные методы (или заставить их вызвать NotImplementedError), загрузчик будет работать только с исходным кодом. Реализация методов позволяет загрузчику работать с файлами исходниками и байт-кодом; он не позволяет загружать sourceless, если предоставляется только байт-код. Файлы байт-кода — это оптимизация для ускорения загрузки за счет удаления этапа парсинга компилятора Python, поэтому специфичный для байт-кода API, не предоставляется.

path_stats(path)

Необязательный абстрактный метод, возвращающий dict, содержащий метаданные об указанном пути. Поддерживаемые словарные ключи:

  • 'mtime' (обязательный): целое число или число с плавающей запятой, представляющее время модификации исходного кода;
  • 'size' (обязательный): размер исходного кода в байтах.

Любые другие ключи в словаре игнорируются, чтобы обеспечить возможность будущих расширений. Если путь не может быть обработан, вызывается OSError.

Добавлено в версии 3.3.

Изменено в версии 3.4: Вызывается OSError вместо NotImplementedError.

path_mtime(path)

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

Не рекомендуется, начиная с версии 3.3: Метод устарел в пользу path_stats(). Вам не нужно его реализовывать, но он по-прежнему доступен для целей совместимости. Вызывается OSError, если путь не может быть обработан.

Изменено в версии 3.4: Вызывается OSError вместо NotImplementedError.

set_data(path, data)

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

Если при записи происходит сбой, из-за того, что путь доступен только для чтения (errno.EACCES/PermissionError), исключение не распространяется.

Изменено в версии 3.4: Больше не вызывает NotImplementedError при вызове.

get_code(fullname)

Реализация InspectLoader.get_code().

exec_module(module)

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

Добавлено в версии 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__.

importlib.resources — Ресурсы


Добавлено в версии 3.7.

Модуль использует систему импорта Python для предоставления доступа к ресурсам в пакетах. Если вы можете импортировать пакет, вы можете получить доступ к ресурсам в этом пакете. Ресурсы можно открывать или читать как в двоичном, так и в текстовом режиме.

Ресурсы примерно аналогичны файлам внутри каталогов, хотя важно помнить, что это всего лишь метафора. Ресурсы и пакеты не должны существовать в виде физических файлов и каталогов в файловой системе.

Примечание

Данный модуль предоставляет функциональные возможности, аналогичные pkg_resources Базовый доступ к ресурсам, без снижения производительности этого пакета. Это упрощает чтение ресурсов, включенных в пакеты, с более стабильной и последовательной семантикой.

Автономная версия модуля содержит дополнительную информацию о использовании importlib.resources и переход с pkg_resources на importlib.resources.

Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать метод get_resource_reader(fullname), как указано в importlib.abc.ResourceReader.

Определены следующие типы.

importlib.resources.Package

Тип Package определяется как Union[str, ModuleType]. Это означает, что там, где функция определяет принятие Package, вы можете передать либо строку, либо модуль. У объектов модулей должен быть разрешаемый __spec__.submodule_search_locations, отличный от None.

importlib.resources.Resource

Данный тип определяет имена ресурсов, передаваемые в различные функции в этом пакете. Определяется как Union[str, os.PathLike].

Доступны следующие функции.

importlib.resources.open_binary(package, resource)

Открывает для двоичного чтения resource внутри package.

package — это либо имя, либо объект модуля, соответствующий требованиям Package. resource — имя ресурса, открываемого в package; он не может содержать разделителей путей и не может иметь подресурсов (т. е. он не может быть каталогом). Данная функция возвращает экземпляр typing.BinaryIO, двоичный поток ввода-вывода, открытый для чтения.

importlib.resources.open_text(package, resource, encoding='utf-8', errors='strict')

Открывает для чтения текста resource внутри package. По умолчанию ресурс открывается для чтения в кодировке UTF-8.

package — это либо имя, либо объект модуля, соответствующий требованиям Package. resource — имя ресурса, открываемого в package; он не может содержать разделителей путей и не может иметь подресурсов (т. е. он не может быть каталогом). encoding и errors имеют то же значение, что и встроенный open().

Данная функция возвращает экземпляр typing.TextIO, текстовый поток ввода-вывода, открытый для чтения.

importlib.resources.read_binary(package, resource)

Читает и возвращает содержимое resource в package как bytes.

package — это либо имя, либо объект модуля, соответствующий требованиям Package. resource — имя ресурса, открываемого в package; он не может содержать разделителей путей и не может иметь подресурсов (т. е. он не может быть каталогом). Данная функция возвращает содержимое ресурса как bytes.

importlib.resources.read_text(package, resource, encoding='utf-8', errors='strict')

Читает и возвращает содержимое resource в package как str. По умолчанию содержимое читается как строгая кодировка UTF-8.

package — это либо имя, либо объект модуля, соответствующий требованиям Package. resource — имя ресурса, открываемого в package; он не может содержать разделителей путей и не может иметь подресурсов (т. е. он не может быть каталогом). encoding и errors имеют то же значение, что и встроенный open(). Данная функция возвращает содержимое ресурса в виде str.

importlib.resources.path(package, resource)

Возвращает путь к resource как фактический путь к файловой системе. Данная функция возвращает менеджер контекста для использования в операторе with. Менеджер контекста предоставляет объект pathlib.Path.

Выход из менеджера контекста очищает любой временный файл, созданный, когда ресурс необходимо извлечь, например из ZIP-файл.

package — это либо имя, либо объект модуля, соответствующий требованиям Package. resource — имя ресурса, открываемого в package; он не может содержать разделителей путей и не может содержать подресурсов (т. е. он не может быть каталогом).

importlib.resources.is_resource(package, name)

Возвращает True, если в пакете есть ресурс с именем name, иначе False. Помните, что каталоги — это не ресурсы! package — это либо имя, либо объект модуля, соответствующий требованиям Package.

importlib.resources.contents(package)

Возвращает итерацию по именованным элементам в пакете. Итеративный объект возвращает ресурсы str (например, файлы) и нересурсы (например, каталоги). Итерируемый объект не рекурсивно переходит в подкаталоги.

package — это либо имя, либо объект модуля, соответствующий требованиям Package.

importlib.machinery — Импортеры и хуки пути


Модуль содержит различные объекты, которые помогают import находить и загружать модули.

importlib.machinery.SOURCE_SUFFIXES

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

Добавлено в версии 3.3.

importlib.machinery.DEBUG_BYTECODE_SUFFIXES

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

Добавлено в версии 3.3.

Не рекомендуется, начиная с версии 3.5: Вместо него используйте BYTECODE_SUFFIXES.

importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES

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

Добавлено в версии 3.3.

Не рекомендуется, начиная с версии 3.5: Вместо него используйте BYTECODE_SUFFIXES.

importlib.machinery.BYTECODE_SUFFIXES

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

Добавлено в версии 3.3.

Изменено в версии 3.5: Значение больше не зависит от __debug__.

importlib.machinery.EXTENSION_SUFFIXES

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

Добавлено в версии 3.3.

importlib.machinery.all_suffixes()

Возвращает объединенный список строк, представляющих все суффиксы файлов для модулей, распознаваемых стандартным механизмом импорта. Это помощник для кода, которому просто нужно знать, потенциально ли путь файловой системы относится к модулю, без каких-либо подробностей о типе модуля (например, inspect.getmodulename()).

Добавлено в версии 3.3.

class importlib.machinery.BuiltinImporter

Импортер для встроенных модулей. Все известные встроенные модули перечислены в sys.builtin_module_names. Данный класс реализует importlib.abc.MetaPathFinder и importlib.abc.InspectLoader ABC.

Только методы класса определяются классом, чтобы облегчить необходимость создания экземпляра.

Изменено в версии 3.5: Как часть PEP 489, встроенный импортер теперь реализует Loader.create_module() и Loader.exec_module()

class importlib.machinery.FrozenImporter

Импортер для замороженных модулей. Данный класс реализует importlib.abc.MetaPathFinder и importlib.abc.InspectLoader ABC.

Только методы класса определяются классом, чтобы облегчить необходимость создания экземпляра.

Изменено в версии 3.4: Получены методы create_module() и exec_module().

class importlib.machinery.WindowsRegistryFinder

Поисковик для модулей, объявленных в реестре Windows. Данный класс реализует importlib.abc.MetaPathFinder ABC.

Только методы класса определяются классом, чтобы облегчить необходимость создания экземпляра.

Добавлено в версии 3.3.

Не рекомендуется, начиная с версии 3.6: Вместо него используйте конфигурацию site. Будущие версии Python могут не включать данный поиск по умолчанию.

class importlib.machinery.PathFinder

Поисковик для атрибутов sys.path и пакета __path__. Данный класс реализует importlib.abc.MetaPathFinder ABC.

Только методы класса определяются классом, чтобы облегчить необходимость создания экземпляра.

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

Метод класса, который пытается найти спецификацию для модуля, указанного fullname в sys.path или, если он определён, в path. Для каждой искомой записи пути проверяется sys.path_importer_cache. Если найден истинный объект, он используется как поисковик пути для поиска искомого модуля. Если запись в sys.path_importer_cache не найдена, то sys.path_hooks ищет поисковик для записи пути и, если находит, сохраняется в sys.path_importer_cache вместе с запросом о модуле. Если ни один поисковик не найден, None сохраняется в кэше и возвращается.

Добавлено в версии 3.4.

Изменено в версии 3.5: Если текущий рабочий каталог, представленный пустой строкой, больше недействителен, то возвращается None, но значение sys.path_importer_cache не кэшируется.

classmethod find_module(fullname, path=None)

Устаревшая оболочка вокруг find_spec().

Не рекомендуется, начиная с версии 3.4: Вместо него используйте find_spec().

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, которая кэширует результаты файловой системы.

Аргумент path — это каталог, за поиск которого отвечает искатель.

Аргумент loader_details представляет собой переменное количество кортежей из двух элементов, каждый из которых содержит загрузчик и последовательность файловых суффиксов, распознаваемых загрузчиком. Ожидается, что загрузчики будут вызываемыми объектами, которые принимают два аргумента: имя модуля и путь к найденному файлу.

Поисковик будет кэшировать содержимое каталога по мере необходимости, выполняя вызовы статистики для каждого поиска модуля, чтобы убедиться, что кеш не устарел. Поскольку устаревание кэша зависит от степени детализации информации операционной системы о состоянии файловой системы, существует потенциальное состояние гонки при поиске модуля, создании нового файла и последующем поиске модуля, который представляет новый файл. Если операции происходят достаточно быстро, чтобы соответствовать гранулярности вызовов статистики, поиск модуля завершится ошибкой. Чтобы этого не произошло, при динамическом создании модуля обязательно вызвать importlib.invalidate_caches().

Добавлено в версии 3.3.

path

Путь, по которому поисковик будет искать.

find_spec(fullname, target=None)

Пытается найти спецификацию для обработки fullname в path.

Добавлено в версии 3.4.

find_loader(fullname)

Пытается найти загрузчик для обработки fullname в path.

invalidate_caches()

Очищает внутренний кеш.

classmethod path_hook(*loader_details)

Метод класса, который возвращает замыкание для использования в sys.path_hooks. Экземпляр FileFinder возвращается замыканием с использованием аргумента пути, переданного замыканию напрямую, и косвенно loader_details.

Если аргумент замыкания не является существующим каталогом, вызывается ImportError.

class importlib.machinery.SourceFileLoader(fullname, path)

Реализация importlib.abc.SourceLoader путём создания подкласса importlib.abc.FileLoader и предоставления некоторых реализаций других методов.

Добавлено в версии 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, которые изменяют формат байт-кода.

Добавлено в версии 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 — это путь к файлу модуля расширения.

Добавлено в версии 3.3.

name

Имя модуля, который поддерживает загрузчик.

path

Путь к модулю расширения.

create_module(spec)

Создаёт объект модуля из заданной спецификации в соответствии с PEP 489.

Добавлено в версии 3.5.

exec_module(module)

Инициализирует данный объект модуля в соответствии с PEP 489.

Добавлено в версии 3.5.

is_package(fullname)

Возвращает True, если путь к файлу указывает на модуль пакета __init__ на основе EXTENSION_SUFFIXES.

get_code(fullname)

Возвращает None, поскольку в модулях расширения отсутствует объект кода.

get_source(fullname)

Возвращает None, т. к. модули расширения не имеют исходного кода.

get_filename(fullname)

Возвращает path.

Добавлено в версии 3.4.

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

Спецификация состояния модуля, связанного с системой импорта. Обычно отображается как атрибут модуля __spec__. В приведенных ниже описаниях имена в скобках обозначают соответствующий атрибут, доступный непосредственно в объекте модуля. Например. module.__spec__.origin == module.__file__. Однако обратите внимание, что, хотя values обычно эквивалентны, они могут отличаться, поскольку между двумя объектами нет синхронизации. Таким образом, можно обновить __path__ модуля во время выполнения, и это не будет автоматически отражено в __spec__.submodule_search_locations.

Добавлено в версии 3.4.

name

(__name__)

Строка для полного имени модуля.

loader

(__loader__)

Загрузчик, который следует использовать при загрузке модуля. Поисковики всегда должен устанавливать это значение.

origin

(__file__)

Имя места, откуда загружается модуль. Например «builtin» для встроенных модулей и имя файла для модулей, загружаемых из исходного кода. Обычно должно быть установлено «origin», но может быть None (по умолчанию), что указывает на то, что не указано (например, для пакетов пространства имён).

submodule_search_locations

(__path__)

Список строк для поиска подмодулей, если это пакет (в противном случае None).

loader_state

Контейнер дополнительных данных, специфичных для модуля, для использования во время загрузки (или None).

cached

(__cached__)

Строка для хранения скомпилированного модуля (или None).

parent

(__package__)

(Только для чтения.) Полное имя пакета, под которым модуль должен быть загружен как подмодуль (или пустая строка для модулей верхнего уровня). Для пакетов это то же самое, что и __name__.

has_location

Логическое значение, указывающее, относится ли атрибут «origin» модуля к загружаемому местоположению.

importlib.util — Служебный код для импортеров


Модуль содержит различные объекты, которые помогают в построении
импортеров.
importlib.util.MAGIC_NUMBER

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

Добавлено в версии 3.4.

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

Возвращает путь PEP 3147/PEP 488 к байт-компилированному файлу, связанному с источником path. Например, если 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 с optimization из '' приведёт к пути байт-кода /foo/bar/__pycache__/baz.cpython-32.pyc. None заставляет использовать уровень оптимизации интерпретатора. Используется строковое представление любого другого значения, поэтому /foo/bar/baz.py с optimization из 2 приведёт к пути байт-кода /foo/bar/__pycache__/baz.cpython-32.opt-2.pyc. Строковое представление optimization может быть только буквенно-цифровым, иначе вызывается ValueError.

Параметр debug_override устарел и может использоваться для переопределения системного значения __debug__. Значение True эквивалентно установке optimization на пустую строку. Значение False совпадает с установкой optimization на 1. Если оба debug_override и optimization не являются None, тогда вызывается TypeError.

Добавлено в версии 3.4.

Изменено в версии 3.5: Был добавлен параметр optimization, а параметр debug_override устарел.

Изменено в версии 3.6: Принимает путеподобный объект.

importlib.util.source_from_cache(path)

Принимая имя файла от path до PEP 3147, возвращает связанный путь к файлу исходного кода. Например, если path — это /foo/bar/__pycache__/baz.cpython-32.pyc, возвращаемый путь будет /foo/bar/baz.py. path не обязательно должен существовать, однако, если он не соответствует формату PEP 3147 или PEP 488, вызывается ValueError. Если sys.implementation.cache_tag не определён, вызывается NotImplementedError.

Добавлено в версии 3.4.

Изменено в версии 3.6: Принимает путеподобный объект.

importlib.util.decode_source(source_bytes)

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

Добавлено в версии 3.4.

importlib.util.resolve_name(name, package)

Преобразует относительное имя модуля в абсолютное.

Если в имя нет начальных точек, то возвращается имя. Это позволяет использовать importlib.util.resolve_name('sys', __spec__.parent) без проверки необходимости аргумента пакета.

Вызывается ValueError, если имя является относительным именем модуля, но пакет является ложным значением (например, None или пустая строка). Также вызывается ValueError, относительное имя будет избегать содержащего его пакета (например, запрос ..bacon из пакета spam).

Добавлено в версии 3.3.

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

Ищет спецификацию для модуля, необязательно относительно указанного имени package. Если модуль находится в sys.modules, то возвращается sys.modules[name].__spec__ (если спецификация не будет None или не установлена, и в этом случае вызывается ValueError). В противном случае выполняется поиск с использованием sys.meta_path. Возвращается None, если спецификация не найдена.

Если name для подмодуля (содержит точку), родительский модуль импортируется автоматически.

name и package работают так же, как и import_module().

Добавлено в версии 3.4.

Изменено в версии 3.7: Вызывает ModuleNotFoundError вместо AttributeError, если package не является пакетом (т. е. у него нет атрибута __path__).

importlib.util.module_from_spec(spec)

Создаёт новый модуль на основе spec и spec.loader.create_module.

Если spec.loader.create_module не возвращает None, то любые ранее существовавшие атрибуты не будут сброшены. Кроме того, при обращении к spec или установке атрибута в модуле не будет вызвано AttributeError.

Данная функция предпочтительнее использования types.ModuleType для создания нового модуля, поскольку spec используется для установки как можно большего количества контролируемых импортом атрибутов в модуле.

Добавлено в версии 3.5.

@importlib.util.module_for_loader

Декоратор для importlib.abc.Loader.load_module() для выбора правильного объекта модуля для загрузки. Ожидается, что у декорированного метода будет сигнатура вызова, принимающую два позиционных аргумента (например, load_module(self, module)), для которых вторым аргументом будет объект модуль, используемый загрузчиком. Обратите внимание, что декоратор не будет работать со статическими методами из-за предположения о двух аргументах.

Декорированный метод примет name загружаемого модуля, как и ожидалось для загрузчика. Если модуль не найден в sys.modules, создаётся новый. Независимо от того, откуда был получен модуль, __loader__ устанавливается в self, а __package__ устанавливается на основе того, что возвращает importlib.abc.InspectLoader.is_package() (если доступно). Данные атрибуты безоговорочно устанавливаются для поддержки перезагрузки.

Если декорированный метод вызывает исключение, и модуль был добавлен в sys.modules, то данный модуль будет удален, чтобы частично инициализированный модуль не остался в sys.modules. Если модуль уже был в sys.modules, то он остаётся один.

Изменено в версии 3.3: __loader__ и __package__ устанавливаются автоматически (когда это возможно).

Изменено в версии 3.4: Устанавливает __name__, __loader__ __package__ безоговорочно для поддержки перезагрузки.

Не рекомендуется, начиная с версии 3.4: Механизм импорта теперь напрямую выполняет все функции, предоставляемые функцией.

@importlib.util.set_loader

Декоратор для importlib.abc.Loader.load_module() для установки атрибута __loader__ в возвращаемом модуле. Если атрибут уже установлен, декоратор ничего не делает. Предполагается, что первый позиционный аргумент обернутого метода (т. е. self) — это то, что должно быть установлено для __loader__.

Изменено в версии 3.4: Устанавливает __loader__, если установлено значение None, как будто атрибут не существует.

Не рекомендуется, начиная с версии 3.4: Механизм импорта позаботится об этом автоматически.

@importlib.util.set_package

Декоратор для importlib.abc.Loader.load_module() для установки атрибута __package__ в возвращаемом модуле. Если __package__ установлен и имеет значение, отличное от None, оно не будет изменено.

Не рекомендуется, начиная с версии 3.4: Механизм импорта позаботится об этом автоматически.

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

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

Добавлено в версии 3.4.

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

Функция фабрика для создания экземпляра ModuleSpec на основе пути к файлу. Отсутствующая информация будет заполнена в спецификации с использованием API-интерфейсов загрузчика и подразумевается, что модуль будет основан на файлах.

Добавлено в версии 3.4.

Изменено в версии 3.6: Принимает путеподобный объект.

importlib.util.source_hash(source_bytes)

Возвращает хэш source_bytes в виде байтов. Файл .pyc на основе хэша встраивает source_hash() содержимого соответствующего исходного файла в свой заголовок.

Добавлено в версии 3.7.

class importlib.util.LazyLoader(loader)

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

Данный класс работает только с загрузчиками, которые определяют exec_module(), поскольку требуется контроль над тем, какой тип модуля используется для модуля. По тем же причинам метод загрузчика create_module() должен возвращать None или тип, для которого его атрибут __class__ может быть изменён вместе с неиспользованием слотов. Наконец, модули, которые заменяют объект, помещенный в sys.modules, не будут работать, т. к. нет способа безопасно правильно заменить ссылки на модули во всем интерпретаторе; вызывается ValueError, если обнаружена такая замена.

Примечание

Для проектов, где время запуска имеет решающее значение, данный класс позволяет потенциально минимизировать стоимость загрузки модуля, если он никогда не используется. Для проектов, где время запуска не имеет существенного значения, использование этого класса сильно не рекомендуется из-за того, что сообщения об ошибках, созданные во время загрузки, откладываются и, таким образом, появляются вне контекста.

Добавлено в версии 3.5.

Изменено в версии 3.6: Начал вызывать create_module(), удалив предупреждение о совместимости для importlib.machinery.BuiltinImporter и importlib.machinery.ExtensionFileLoader.

classmethod factory(loader)

Статический метод, возвращающий вызываемый объект, создающий отложенный загрузчик. Предназначен для использования в ситуациях, когда загрузчик передаётся по классу, а не по экземпляру.

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().

import importlib.util
import sys

# Для иллюстративных целей.
name = 'itertools'

if name in sys.modules:
    print(f"{name!r} уже в sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
    # Если вы решили выполнить фактический импорт...
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    print(f"{name!r} был импортирован")
else:
    print(f"не могу найти {name!r} модуль")

Прямой импорт исходного файла

Чтобы напрямую импортировать исходный файл Python, используйте следующий рецепт (только Python 3.5 и новее):

import importlib.util
import sys

# Для иллюстративных целей.
import tokenize
file_path = tokenize.__file__
module_name = tokenize.__name__

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)

Настройка импортера

Для глубокой настройки импорта обычно требуется реализовать импортер. Это означает управление как поисковиком, так и загрузчиком. Для поисковиков есть два варианта на выбор в зависимости от ваших потребностей: поисковик мета-пути или поисковик пути. Первое — это то, что помещаете в sys.meta_path, а второе — это то, что создаётся, используя хук пути входа в sys.path_hooks, который работает с записями sys.path, чтобы потенциально создаёт поисковик. Данный пример проиллюстрирует, как зарегистрировать собственные импортеры, чтобы импорт их использовал (чтобы создать импортер для себя, читайте документацию для соответствующих классов, определённых в данном пакете):

import importlib.machinery
import sys

# Только для иллюстративных целей.
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
                  importlib.machinery.SOURCE_SUFFIXES)

# Настройка поиска метапутей.
# Обязательное помещение поисковика в правильное место в списке с точки
# зрения приоритета.
sys.meta_path.append(SpamMetaPathFinder)

# Настройка пути входа поисковика.
# Обязательно поместите хук пути в нужное место в списке с точки
# зрения приоритета.
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))

Приблизительно importlib.import_module()

Сам импорт реализован в коде Python, что позволяет использовать большую часть механизма импорта через importlib. Следующее помогает проиллюстрировать различные API, которые предоставляет importlib, предоставляя приблизительную реализацию importlib.import_module() (Python 3.4 и новее для использования importlib, Python 3.6 и новее для других частей кода).

import importlib.util
import sys

def import_module(name, package=None):
    """Примерная реализация импорта."""
    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