Spec-Zone.ru › Python 3.14

importlib — Реализация импорта

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

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

Введение

У пакета importlib три назначения.

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

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

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

  • importlib.metadata предоставляет доступ к метаданным сторонних дистрибутивов.
  • importlib.resources предоставляет средства для доступа к «ресурсам» пакетов Python, не являющимся кодом.

См. также

Оператор import

Справочник по языку для оператора import.

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

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

The __import__() function

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

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

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

PEP 235

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

PEP 263

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

PEP 302

Новые хуки импорта

PEP 328

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

PEP 366

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

PEP 420

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

PEP 451

Тип ModuleSpec для системы импорта

PEP 488

Устранение файлов PYO

PEP 489

Многоэтапная инициализация модулей расширений

PEP 552

Детерминированные файлы pyc

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

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

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

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

importlib.reload(module)

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

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

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

Следует учитывать и другие особенности:

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

try:
    cache
except NameError:
    cache = {}

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

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

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

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

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

Предупреждение

Эта функция не является потокобезопасной. Её вызов из нескольких потоков может привести к непредсказуемому поведению. Для потокобезопасной повторной загрузки модулей рекомендуется использовать threading.Lock или другие примитивы синхронизации.

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

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

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

Иерархия ABC:

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

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

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

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

find_spec(fullname, path, target=None)

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

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

invalidate_caches()

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

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

class importlib.abc.PathEntryFinder

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

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

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

find_spec(fullname, target=None)

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

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

invalidate_caches()

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

class importlib.abc.Loader

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

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

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

create_module(spec)

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

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

  • module.__name__
  • module.__file__
  • module.__cached__ (устарел)
  • module.__path__
  • module.__package__ (устарел)
  • module.__loader__ (устарел)

Если доступен exec_module(), обеспечивается обратная совместимость.

Изменено в версии 3.4: При вызове вызывается исключение ImportError вместо NotImplementedError. Если доступен exec_module(), предоставляется соответствующая функциональность.

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

class importlib.abc.ResourceLoader

Заменён классом TraversableResources

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

Устарел с версии 3.7: Этот ABC устарел; вместо него следует поддерживать загрузку ресурсов через importlib.resources.abc.TraversableResources. Этот класс существует только для обратной совместимости с другими ABC этого модуля.

abstractmethod get_data(path)

Абстрактный метод, возвращающий байты данных, расположенных по адресу path. Загрузчики, использующие файловое хранилище, позволяющее сохранять произвольные данные, могут реализовать этот абстрактный метод для прямого доступа к сохранённым данным. Если path не найден, следует вызвать исключение OSError. Предполагается, что 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, будет удалён в версии 3.15: вместо него используйте 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)

Вызывает метод load_module() суперкласса.

Устарел с версии 3.4, будет удалён в версии 3.15: Вместо него используйте Loader.exec_module().

abstractmethod get_filename(fullname)

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

abstractmethod get_data(path)

Читает path как двоичный файл и возвращает содержащиеся в нём байты.

class importlib.abc.SourceLoader

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

  • ResourceLoader.get_data()
  • ExecutionLoader.get_filename()

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

Абстрактные методы, определённые этим классом, добавляют поддержку необязательных файлов байт-кода. Если эти необязательные методы не реализованы (или вызывают 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)

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

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

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

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

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

class importlib.machinery.FrozenImporter

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

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

Изменено в версии 3.4: Добавлены методы create_module() и exec_module().

class importlib.machinery.WindowsRegistryFinder

Искатель модулей, зарегистрированных в реестре Windows. Этот класс реализует ABC importlib.abc.MetaPathFinder.

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

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

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

class importlib.machinery.PathFinder

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

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

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 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 — переменное количество кортежей из двух элементов, каждый из которых содержит загрузчик и последовательность суффиксов файлов, распознаваемых этим загрузчиком. Предполагается, что загрузчики являются вызываемыми объектами, принимающими два аргумента: имя модуля и путь к найденному файлу.

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

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

path

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

find_spec(fullname, target=None)

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

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

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, будет удалено в версии 3.15: Вместо этого используйте 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, будет удалено в версии 3.15: Вместо этого используйте importlib.abc.Loader.exec_module().

class importlib.machinery.ExtensionFileLoader(fullname, path)

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

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

Обратите внимание: по умолчанию импорт модуля расширения в подинтерпретаторах завершается ошибкой, если в нём не реализована многоэтапная инициализация (см. PEP 489), даже если в остальных случаях импорт прошёл бы успешно.

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

Изменено в версии 3.12: Для использования в подинтерпретаторах теперь требуется многоэтапная инициализация.

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.__spec__.origin == module.__file__. Однако обратите внимание, что, хотя значения обычно эквивалентны, они могут различаться, поскольку синхронизация между двумя объектами отсутствует. Например, атрибут __file__ модуля можно обновить во время выполнения, и это изменение не будет автоматически отражено в атрибуте __spec__.origin модуля, и наоборот.

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

name

Полное имя модуля (см. module.__name__). Искатель всегда должен задавать для этого атрибута непустую строку.

loader

Загрузчик, использованный для загрузки модуля (см. module.__loader__). Искатель всегда должен задавать этот атрибут.

origin

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

submodule_search_locations

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

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

loader_state

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

cached

Имя файла с скомпилированным кодом модуля (см. module.__cached__). Искатель всегда должен задавать этот атрибут, но для модулей, которым не требуется хранить скомпилированный код, его значение может быть None.

parent

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

has_location

True, если origin спецификации указывает на доступное для загрузки местоположение, и False в противном случае. Это значение влияет на интерпретацию origin и на заполнение атрибута __file__ модуля.

class importlib.machinery.AppleFrameworkLoader(name, path)

Специализация importlib.machinery.ExtensionFileLoader, способная загружать модули расширений в формате Framework.

Для совместимости с App Store для iOS все двоичные модули в приложении для iOS должны быть динамическими библиотеками, содержащимися в framework с соответствующими метаданными и хранящимися в папке Frameworks упакованного приложения. В каждом framework может быть только один двоичный файл, и вне папки Frameworks не должно быть исполняемых двоичных файлов.

Чтобы выполнить это требование, при работе в iOS двоичные файлы модулей расширений упаковываются не как файлы .so в sys.path, а как отдельные автономные frameworks. Для обнаружения таких frameworks этот загрузчик регистрируется для расширения файла .fwork, а файл .fwork служит заполнителем в исходном расположении двоичного файла в sys.path. Файл .fwork содержит путь к фактическому двоичному файлу в папке Frameworks относительно пакета приложения. Чтобы можно было сопоставить двоичный файл, упакованный в framework, с исходным расположением, framework должен содержать файл .origin, в котором указано расположение файла .fwork относительно пакета приложения.

Например, рассмотрим случай импорта from foo.bar import _whiz, где _whiz реализован двоичным модулем sources/foo/bar/_whiz.abi3.so, а sources — это расположение, зарегистрированное в sys.path относительно пакета приложения. Этот модуль должен распространяться как Frameworks/foo.bar._whiz.framework/foo.bar._whiz (имя framework формируется из полного пути импорта модуля), а файл Info.plist в каталоге .framework должен указывать, что двоичный файл является framework. Модуль foo.bar._whiz будет представлен в исходном расположении файлом-маркером sources/foo/bar/_whiz.abi3.fwork, содержащим путь Frameworks/foo.bar._whiz/foo.bar._whiz. В framework также будет содержаться Frameworks/foo.bar._whiz.framework/foo.bar._whiz.origin с путем к файлу .fwork.

При загрузке модуля этим загрузчиком __file__ модуля будет указывать на расположение файла .fwork. Это позволяет коду использовать __file__ модуля как точку отсчета для обхода файловой системы. Однако в origin спецификации будет указано расположение фактического двоичного файла в папке .framework.

Проект Xcode, собирающий приложение, отвечает за преобразование всех файлов .so, находящихся в PYTHONPATH, во frameworks в папке Frameworks (включая удаление расширений файлов модулей, добавление метаданных framework и подпись полученного framework), а также за создание файлов .fwork и .origin. Обычно это выполняется на одном из этапов сборки проекта Xcode; подробные сведения о настройке этого этапа сборки см. в документации по iOS.

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

Доступность: iOS.

name

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

path

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

importlib.util – Вспомогательный код для импортёров

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

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

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 формируется из текущего тега magic (см. 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)

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

Если у 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)

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

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

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

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

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

importlib.util.module_from_spec(spec)

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

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

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

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

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.

importlib.util._incompatible_extension_module_restrictions(*, disable_check)

Менеджер контекста, который позволяет временно пропустить проверку совместимости модулей расширений. По умолчанию проверка включена и завершается ошибкой, если модуль с однофазной инициализацией импортируется во вложенный интерпретатор. Ошибка также возникает при импорте модуля с многофазной инициализацией, который явно не поддерживает отдельный GIL для каждого интерпретатора, в интерпретатор с собственным GIL.

Обратите внимание, что эта функция предназначена для редкого случая, который, вероятно, со временем исчезнет. Скорее всего, это не то, что вам нужно.

Того же эффекта можно добиться, реализовав базовый интерфейс многофазной инициализации (PEP 489) и заявив о поддержке нескольких интерпретаторов (или отдельного GIL для каждого интерпретатора).

Предупреждение

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

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

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

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

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

Этот способ следует использовать с осторожностью: он лишь приблизительно имитирует инструкцию импорта, в которой путь к файлу задаётся напрямую, а не выполняется поиск в sys.path. Сначала следует рассмотреть альтернативы, например изменить sys.path, если нужен полноценный модуль, или использовать runpy.run_path(), если подходит глобальное пространство имён, созданное при выполнении файла Python.

Для прямого импорта исходного файла Python по пути используйте следующий способ:

import importlib.util
import sys


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


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

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

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

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

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

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

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

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

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/importlib.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API