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

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

Исходный код: Lib/importlib/__init__.py


Вступление

Пакет importlib предназначен для трех целей.

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

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

В-третьих, пакет содержит модули, предоставляющие дополнительные функциональные возможности для управления различными аспектами пакетов Python:

  • importlib.metadata предоставляет доступ к метаданным из сторонних дистрибутивов.

  • importlib.resources предоставляет процедуры для доступа к некодируемым «ресурсам» из пакетов Python.

См.также

Оператор import

Ссылка на язык для инструкции import.

Packages specification

Оригинальная спецификация пакетов. С момента написания этого документа некоторые семантические изменения были внесены (например, перенаправление на основе None в sys.modules).

Функция __import__()

Оператор import является синтаксическим сахаром для этой функции.

Инициализация пути поиска модуля sys.path

Инициализация sys.path.

PEP 235

Импорт на платформах без учета регистра

:pep:`263`Импорт на платформах без учета регистра

Определение кодировок исходного кода Python

PEP 302

Новые крючки для импорта

PEP 328

Импорт: Многострочный и абсолютный/относительный

PEP 366

Основной модуль явного относительного импорта

PEP 420

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

PEP 451

Тип спецификации модуля для системы импорта

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)

Найдите загрузчик для модуля, необязательно в пределах указанного пути. Если модуль находится в 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.

Изменено в версии 3.10: Замечаются пакеты пространства имен, созданные/установленные в другом расположении sys.path после того, как то же пространство имен уже было импортировано.

importlib.reload(module)

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

Когда выполняется reload():

  • Код модуля Python перекомпилируется, и код на уровне модуля выполняется повторно, определяя новый набор объектов, которые привязаны к именам в словаре модуля, путем повторного использования loader, который первоначально загружал модуль. Функция 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 – Абстрактные базовые классы, связанные с импортом

Исходный код: Lib/importlib/abc.py


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

Иерархия ABC:

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

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

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

abstractmethod find_module(fullname, path=None)

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

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

Не рекомендуется, начиная с версии 3.10: Вместо этого реализуйте MetaPathFinder.find_spec() или PathEntryFinder.find_spec().

class importlib.abc.MetaPathFinder

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

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

Изменено в версии 3.10: Больше не является подклассом Finder.

find_spec(fullname, path, target=None)

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

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

find_module(fullname, path)

Устаревший метод поиска loader для указанного модуля. Если это импорт верхнего уровня, 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

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

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

Изменено в версии 3.10: Больше не является подклассом Finder.

find_spec(fullname, target=None)

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

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

find_loader(fullname)

Устаревший метод поиска loader для указанного модуля. Возвращает 2-й кортеж из (loader, portion), где portion - это последовательность расположений файловой системы, составляющих часть пакета пространства имен. Загрузчиком может быть None, при этом указывается portion для обозначения вклада местоположений файловой системы в пакет пространства имен. Пустой список можно использовать для обозначения portion, чтобы указать, что загрузчик не является частью пакета пространства имен. Если loader равно None, а 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()

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

class importlib.abc.Loader

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

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

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

create_module(spec)

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

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

Изменено в версии 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__

    Полное имя модуля. Это '__main__' для выполняемого модуля.

  • __file__

    Расположение, которое loader использовалось для загрузки модуля. Например, для модулей, загруженных из файла .py, это имя файла. Оно задано не для всех модулей (например, встроенных модулей).

  • __cached__

    Имя файла скомпилированной версии кода модуля. Оно задается не во всех модулях (например, встроенных модулях).

  • __path__

    Список местоположений, в которых будут найдены подмодули пакета. В большинстве случаев это один каталог. Система импорта передает этот атрибут __import__() и средствам поиска таким же образом, как и sys.path, но только для пакета. Он не задается для модулей, не входящих в пакет, поэтому его можно использовать как индикатор того, что модуль является пакетом.

  • __package__

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

  • __loader__

    loader, используемый для загрузки модуля.

Если доступно значение 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__() будет использовать результат этого метода соответствующим образом.

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

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

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

class importlib.abc.ResourceLoader

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

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

abstractmethod get_data(path)

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

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

class importlib.abc.InspectLoader

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

get_code(fullname)

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

Примечание

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

Изменено в версии 3.4: Это уже не абстрактный подход, а конкретная реализация.

abstractmethod get_source(fullname)

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

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

is_package(fullname)

Необязательный метод, возвращающий значение true, если модуль является пакетом, и значение false в противном случае. ImportError вызывается, если loader не удается найти модуль.

Изменено в версии 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’s load_module().

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

abstractmethod get_filename(fullname)

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

abstractmethod get_data(path)

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

class importlib.abc.SourceLoader

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

Абстрактные методы, определенные этим классом, предназначены для добавления необязательной поддержки файлов с байт-кодом. Если не реализовать эти необязательные методы (или если они не вызовут NotImplementedError), загрузчик будет работать только с исходным кодом. Реализация этих методов позволяет загрузчику работать с файлами с исходным кодом * и байт-кодом*; это не позволяет выполнять загрузку без исходного кода, где предоставляется только байт-код. Файлы с байт-кодом оптимизированы для ускорения загрузки за счет удаления этапа синтаксического анализа в компиляторе 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)

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

Когда запись в path завершается ошибкой, поскольку путь доступен только для чтения (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.machinery – Импортеры и перехватчики путей

Исходный код: Lib/importlib/machinery.py


Этот модуль содержит различные объекты, которые помогают 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

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

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

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

class importlib.machinery.FrozenImporter

importer для замороженных модулей. Этот класс реализует importlib.abc.MetaPathFinder и importlib.abc.InspectLoader Азбуки.

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

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

class importlib.machinery.WindowsRegistryFinder

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

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

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

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

class importlib.machinery.PathFinder

Finder для атрибутов sys.path и package __path__. Этот класс реализует importlib.abc.MetaPathFinder ABC.

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

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

Метод класса, который пытается найти spec для модуля, указанного с помощью fullname в sys.path или, если он определен, в path. Для каждой записи пути, в которой выполняется поиск, проверяется sys.path_importer_cache. Если найден объект, не являющийся ложным, то он используется в качестве path entry finder для поиска искомого модуля. Если запись не найдена в 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 - это каталог, по которому программа finder отвечает за поиск.

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

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

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

path

Путь, по которому finder будет выполнять поиск.

find_spec(fullname, target=None)

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

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

find_loader(fullname)

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

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

invalidate_caches()

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

classmethod path_hook(*loader_details)

Метод класса, который возвращает замыкание для использования в sys.path_hooks. Экземпляр FileFinder возвращается замыканием, используя аргумент path, заданный непосредственно замыканию, и 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.NamespaceLoader(name, path, path_finder)

Конкретная реализация importlib.abc.InspectLoader для пакетов пространства имен. Это псевдоним для закрытого класса, который становится общедоступным только для самоанализа атрибута __loader__ для пакетов пространства имен:

>>> 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

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

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

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

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

name

(__name__)

Полное имя модуля. Для finder всегда следует присваивать этому атрибуту значение непустой строки.

loader

(__loader__)

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

origin

(__file__)

Расположение, которое loader следует использовать для загрузки модуля. Например, для модулей, загружаемых из файла .py, это имя файла. Для finder всегда следует присваивать этому атрибуту значимое значение, чтобы использовать loader. В необычном случае, когда его нет (например, для пакетов пространства имен), для него должно быть установлено значение None.

submodule_search_locations

(__path__)

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

loader_state

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

cached

(__cached__)

Имя файла скомпилированной версии кода модуля. Этот атрибут всегда должен быть finder, но он может быть None для модулей, которым не требуется сохранять скомпилированный код.

parent

(__package__)

(Доступно только для чтения) Полное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же самое, что name.

has_location
True если значение спецификации origin относится к загружаемому местоположению,

False в противном случае. Это значение влияет на то, как интерпретируется origin и как заполняется __file__ модуля.

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

Исходный код: Lib/importlib/util.py


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

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 с оптимизацией, равной '', приведет к пути байт-кода, равному /foo/bar/__pycache__/baz.cpython-32.pyc. None что приводит к использованию уровня оптимизации интерпретатора. Используется строковое представление любого другого значения, поэтому /foo/bar/baz.py с оптимизацией 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: Принимает значение 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.

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

Изменено в версии 3.6: Принимает значение path-like object.

importlib.util.decode_source(source_bytes)

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

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

importlib.util.resolve_name(name, package)

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

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

ImportError вызывается, если name является относительным именем модуля, а package - ложным значением (например, None или пустой строкой). ImportError также вызывается, если относительное имя не используется в содержащем его пакете (например, при запросе ..bacon из пакета spam).

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

Изменено в версии 3.9: Чтобы улучшить согласованность с инструкциями по импорту, увеличьте значение ImportError вместо ValueError для недопустимых попыток относительного импорта.

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

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

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

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

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

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

importlib.util.module_from_spec(spec)

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

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

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

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

@importlib.util.module_for_loader

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

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

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

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

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

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

@importlib.util.set_loader

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

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

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

@importlib.util.set_package

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

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

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

Фабричная функция для создания экземпляра ModuleSpec на основе загрузчика. Параметры имеют то же значение, что и для ModuleSpec. Функция использует доступный loader 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: Принимает значение path-like object.

importlib.util.source_hash(source_bytes)

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

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

class importlib.util.LazyLoader(loader)

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

Этот класс ** работает только с загрузчиками, которые определяют exec_module(), поскольку требуется контроль над тем, какой тип модуля используется для данного модуля. По тем же причинам метод загрузчика create_module() должен возвращать None или тип, для которого его атрибут __class__ может быть изменен, а также не использовать slots. Наконец, модули, которые заменяют объект, помещенный в 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().

Обратите внимание, что если 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")

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

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

import importlib.util
import sys

# For illustrative purposes.
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)

Реализация отложенного импорта

В приведенном ниже примере показано, как реализовать отложенный импорт:

>>> 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

Создание импортера

Для глубокой настройки импорта обычно требуется реализовать importer. Это означает управление как finder, так и loader аспектами. Для гурманов есть два вкуса на выбор в зависимости от ваших потребностей: meta path finder или path entry finder. Первое - это то, что вы бы добавили в sys.meta_path, в то время как второе - это то, что вы создаете, используя path entry hook в sys.path_hooks, которое работает с sys.path записями, чтобы потенциально создать finder. В этом примере показано, как зарегистрировать ваши собственные импортеры, чтобы их можно было использовать в import (чтобы создать импортер для себя, ознакомьтесь с документацией по соответствующим классам, определенным в этом пакете).:

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

Сам импорт реализован в коде Python, что позволяет использовать большинство механизмов импорта через importlib. Ниже приведены примеры различных API, которые предоставляет importlib, на примере примерной реализации 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
Вернуться на верх