Содержание страницы
29.6. importlib – реализация import¶importlib – An implementation of import
Новое в версии 3.1.
29.6.1. Введение¶Introduction
Цель пакета importlib двояка. Во-первых, предоставить реализацию инструкции import (и, соответственно, функции __import__()) в исходном коде Python. Это даёт реализацию import, переносимую на любой интерпретатор Python. Также это предоставляет эталонную реализацию, которую проще понять, чем реализацию на другом языке программирования.
Во-вторых, компоненты для реализации import доступны в этом пакете, что упрощает создание пользовательских объектов (в общем случае называемых импортёром) для участия в процессе импорта. Подробности о пользовательских импортёрах можно найти в PEP 302.
См. также
- Оператор import
- Справочное руководство по оператору import.
- Спецификация пакетов
- Оригинальная спецификация пакетов. Некоторые аспекты семантики изменились с момента написания этого документа (например, перенаправление на основе None в sys.modules).
- Функция __import__()
- Оператор import – это синтаксический сахар для этой функции.
- PEP 235
- Импорт на платформах, нечувствительных к регистру
- PEP 263
- Определение кодировок исходного кода Python
- PEP 302
- Новые хуки импорта
- PEP 328
- Импорт: многострочный и абсолютный/относительный
- PEP 366
- Явные относительные импорты в главном модуле
- PEP 3120
- Использование UTF-8 в качестве кодировки исходного кода по умолчанию
- PEP 3147
- Каталоги репозитория PYC
29.6.2. Функции¶Functions
- importlib.__import__(name, globals={}, locals={}, fromlist=list(), level=0)¶
Реализация встроенной функции __import__().
- importlib.import_module(name, package=None)¶
Импортирует модуль. Аргумент name задаёт импортируемый модуль в абсолютном или относительном виде (например, pkg.mod или ..mod). Если имя указано в относительной форме, то аргумент package должен быть задан как имя пакета, который будет служить точкой привязки для разрешения имени пакета (например, import_module('..mod', 'pkg.subpkg') импортирует pkg.mod).
Функция import_module() действует как упрощающая обёртка вокруг importlib.__import__(). Это означает, что вся семантика функции выводится из importlib.__import__(), включая требование, чтобы пакет, из которого происходит импорт, был ранее импортирован (т.е. package должен быть уже импортирован). Самое важное отличие в том, что import_module() возвращает самый вложенный пакет или модуль, который был импортирован (например, pkg.mod), в то время как __import__() возвращает пакет или модуль верхнего уровня (например, pkg).
29.6.3. importlib.abc – Абстрактные базовые классы, связанные с импортом¶importlib.abc – Abstract base classes related to import
Модуль importlib.abc содержит все основные абстрактные базовые классы, используемые import. Также предоставляются некоторые подклассы основных абстрактных базовых классов для помощи в реализации базовых ABC.
- class importlib.abc.Finder¶
Абстрактный базовый класс, представляющий искатель. См. PEP 302 для точного определения искателя.
- find_module(fullname, path=None)¶
Абстрактный метод для поиска загрузчика для указанного модуля. Если искатель найден в sys.meta_path и искомый модуль является подпакетом или модулем, то path будет значением __path__ из родительского пакета. Если загрузчик не найден, возвращается None.
- class importlib.abc.Loader¶
Абстрактный базовый класс для загрузчика. См. PEP 302 для точного определения загрузчика.
- load_module(fullname)¶
Абстрактный метод для загрузки модуля. Если модуль невозможно загрузить, возбуждается ImportError, иначе возвращается загруженный модуль.
Если запрошенный модуль уже существует в sys.modules, то он должен быть использован и перезагружен. В противном случае загрузчик должен создать новый модуль и вставить его в sys.modules до начала загрузки, чтобы предотвратить рекурсию при импорте. Если загрузчик вставил модуль, но загрузка завершилась неудачей, он должен удалить его из sys.modules; модули, уже находившиеся в sys.modules до начала выполнения загрузчика, следует оставить нетронутыми. Декоратор importlib.util.module_for_loader() обрабатывает все эти детали.
Загрузчик должен установить несколько атрибутов модуля. (Обратите внимание, что некоторые из этих атрибутов могут измениться при перезагрузке модуля.)
- __name__
Имя модуля.
- __file__
Путь к месту хранения данных модуля (не задан для встроенных модулей).
- __path__
Список строк, задающих путь поиска внутри пакета. Этот атрибут не задан для модулей.
- __package__
Родительский пакет для модуля/пакета. Если модуль находится на верхнем уровне, то его значением является пустая строка. Декоратор importlib.util.set_package() может обработать детали для __package__.
- __loader__
Загрузчик, используемый для загрузки модуля. (Он не устанавливается встроенным механизмом импорта, но должен быть установлен при использовании загрузчика.)
- class importlib.abc.ResourceLoader¶
Абстрактный базовый класс для загрузчика, который реализует опциональный протокол PEP 302 для загрузки произвольных ресурсов из бэкенда хранилища.
- get_data(path)¶
Абстрактный метод, возвращающий байты данных по заданному пути path. Загрузчики, имеющие файлоподобное хранилище, позволяющее сохранять произвольные данные, могут реализовать этот абстрактный метод для прямого доступа к хранимым данным. IOError должно быть возбуждено, если path не найден. Ожидается, что path будет построен с использованием атрибута модуля __file__ или элемента из __path__ пакета.
- class importlib.abc.InspectLoader¶
Абстрактный базовый класс для загрузчика, который реализует опциональный протокол PEP 302 для загрузчиков, которые инспектируют модули.
- get_code(fullname)¶
Абстрактный метод, возвращающий объект кода для модуля. None возвращается, если модуль не имеет объекта кода (например, встроенный модуль). ImportError возбуждается, если загрузчик не может найти запрошенный модуль.
- get_source(fullname)¶
Абстрактный метод, возвращающий исходный код модуля. Он возвращается в виде текстовой строки с использованием универсальных символов новой строки, преобразуя все распознаваемые разделители строк в символы '\n'. Возвращает None, если исходный код недоступен (например, для встроенного модуля). Вызывает ImportError, если загрузчик не может найти указанный модуль.
- is_package(fullname)¶
Абстрактный метод, возвращающий истинное значение, если модуль является пакетом, и ложное в противном случае. ImportError возбуждается, если загрузчик не может найти модуль.
- class importlib.abc.ExecutionLoader¶
Абстрактный базовый класс, наследующий от InspectLoader, который при реализации помогает выполнять модуль как скрипт. Этот ABC представляет необязательный протокол PEP 302.
- get_filename(fullname)¶
Абстрактный метод, возвращающий значение __file__ для указанного модуля. Если путь недоступен, возбуждается ImportError.
Если исходный код доступен, метод должен возвращать путь к файлу исходного кода, независимо от того, использовался ли байткод для загрузки модуля.
- class importlib.abc.SourceLoader¶
Абстрактный базовый класс для реализации загрузки исходных (и, опционально, байт-кодовых) файлов. Этот класс наследует как от ResourceLoader, так и от ExecutionLoader, требуя реализации следующих методов:
- ExecutionLoader.get_filename()
Должен возвращать только путь к файлу исходного кода; загрузка без исходного кода не поддерживается.
Абстрактные методы, определённые в этом классе, предназначены для добавления необязательной поддержки файлов байткода. Если не реализовывать эти необязательные методы, загрузчик сможет работать только с исходным кодом. Реализация методов позволяет загрузчику работать с файлами исходного кода и байткода; но он не поддерживает загрузку без исходного кода, когда предоставляется только байткод. Файлы байткода являются оптимизацией, ускоряющей загрузку за счёт исключения этапа разбора компилятором Python, и поэтому никакой специфичный для байткода API не предоставляется.
- path_mtime(self, path)¶
Необязательный абстрактный метод, возвращающий время изменения указанного пути.
- set_data(self, path, data)¶
Необязательный абстрактный метод, записывающий указанные байты в файл по заданному пути. Все недостающие промежуточные каталоги должны быть созданы автоматически.
Если запись по пути не удаётся, потому что путь доступен только для чтения (errno.EACCES), не распространяйте исключение.
- get_code(self, fullname)¶
Конкретная реализация метода InspectLoader.get_code().
- load_module(self, fullname)¶
Конкретная реализация метода Loader.load_module().
- get_source(self, fullname)¶
Конкретная реализация метода InspectLoader.get_source().
- is_package(self, fullname)¶
Конкретная реализация InspectLoader.is_package(). Модуль считается пакетом, если его путь – это файл с именем __init__ после удаления расширения файла.
- class importlib.abc.PyLoader¶
Абстрактный базовый класс, наследующий от ExecutionLoader и ResourceLoader, предназначенный для упрощения загрузки модулей на Python (байткод не обрабатывается; см. SourceLoader для ABC исходного кода/байткода). Подкласс, реализующий этот ABC, должен заботиться только о том, как хранится исходный код; все остальные детали загрузки исходного кода Python будут обрабатываться конкретными реализациями ключевых методов.
Устарело с версии 3.2: Этот класс устарел в пользу SourceLoader и будет удалён в Python 3.4. Смотрите ниже, как создать подкласс, совместимый с Python 3.1 и новее.
Если требуется совместимость с Python 3.1, используйте следующий подход для реализации подкласса, который будет работать с Python 3.1 и выше (обязательно реализуйте ExecutionLoader.get_filename()):
try: from importlib.abc import SourceLoader except ImportError: from importlib.abc import PyLoader as SourceLoader class CustomLoader(SourceLoader): def get_filename(self, fullname): """Возвращает путь к исходному файлу.""" # Реализует ... def source_path(self, fullname): """Реализует source_path с помощью get_filename.""" try: return self.get_filename(fullname) except ImportError: return None def is_package(self, fullname): """Реализовать is_package путём поиска файла __init__ имя, возвращаемое get_filename.""" filename = os.path.basename(self.get_filename(fullname)) return os.path.splitext(filename)[0] == '__init__'
- source_path(fullname)¶
Абстрактный метод, возвращающий путь к исходному коду модуля. Должен возвращать None, если исходного кода нет. Возбуждает ImportError, если загрузчик знает, что не может обработать модуль.
- get_filename(fullname)¶
Конкретная реализация importlib.abc.ExecutionLoader.get_filename(), которая опирается на source_path(). Если source_path() возвращает None, то возбуждается ImportError.
- load_module(fullname)¶
Конкретная реализация importlib.abc.Loader.load_module(), которая загружает исходный код Python. Вся необходимая информация поступает из абстрактных методов, требуемых этим ABC. Единственное существенное предположение, которое делает этот метод, заключается в том, что при загрузке пакета __path__ устанавливается в [os.path.dirname(__file__)].
- get_code(fullname)¶
Конкретная реализация importlib.abc.InspectLoader.get_code(), которая создаёт объекты кода из исходного кода Python, запрашивая исходный код (с помощью source_path() и get_data()) и компилируя его с помощью встроенной функции compile().
- get_source(fullname)¶
Конкретная реализация importlib.abc.InspectLoader.get_source(). Использует importlib.abc.ResourceLoader.get_data() и source_path() для получения исходного кода. Он пытается угадать кодировку исходного кода с помощью tokenize.detect_encoding().
- class importlib.abc.PyPycLoader¶
Абстрактный базовый класс, наследующий от PyLoader. Этот ABC предназначен для помощи в создании загрузчиков, поддерживающих как исходный код Python, так и байткод.
Устарело с версии 3.2: Этот класс устарел в пользу SourceLoader и для правильной поддержки PEP 3147. Если требуется совместимость с Python 3.1, реализуйте одновременно SourceLoader и PyLoader; инструкции по этому поводу приведены в документации PyLoader. Обратите внимание, что это решение не поддерживает загрузку без исходного кода (только байт-код); поддерживается только загрузка исходного кода и байт-кода.
- source_mtime(fullname)¶
Абстрактный метод, который возвращает время изменения исходного кода указанного модуля. Время изменения должно быть целым числом. Если исходного кода нет, вернуть None. Если модуль не найден, возбуждается ImportError.
- bytecode_path(fullname)¶
Абстрактный метод, который возвращает путь к байткоду указанного модуля, если он существует. Возвращает None, если байткода (пока) нет. Возбуждает ImportError, если загрузчик знает, что не может обработать модуль.
- get_filename(fullname)¶
A concrete implementation of ExecutionLoader.get_filename() that relies on PyLoader.source_path() and bytecode_path(). If source_path() returns a path, then that value is returned. Else if bytecode_path() returns a path, that path will be returned. If a path is not available from both methods, ImportError is raised.
- write_bytecode(fullname, bytecode)¶
An abstract method which has the loader write bytecode for future use. If the bytecode is written, return True. Return False if the bytecode could not be written. This method should not be called if sys.dont_write_bytecode is true. The bytecode argument should be a bytes string or bytes array.
29.6.4. importlib.machinery – Импортёры и хуки путей¶importlib.machinery – Importers and path hooks
Этот модуль содержит различные объекты, которые помогают import находить и загружать модули.
- class importlib.machinery.BuiltinImporter¶
An importer for built-in modules. All known built-in modules are listed in sys.builtin_module_names. This class implements the importlib.abc.Finder and importlib.abc.InspectLoader ABCs.
В этом классе определены только методы класса, чтобы не было необходимости в создании экземпляров.
- class importlib.machinery.FrozenImporter¶
An importer for frozen modules. This class implements the importlib.abc.Finder and importlib.abc.InspectLoader ABCs.
В этом классе определены только методы класса, чтобы не было необходимости в создании экземпляров.
- class importlib.machinery.PathFinder¶
Finder для sys.path. Этот класс реализует importlib.abc.Finder ABC.
Этот класс не полностью отражает семантику import в отношении sys.path. Не предполагается никаких неявных хуков путей для упрощения класса и его семантики.
В этом классе определены только методы класса, чтобы не было необходимости в создании экземпляров.
- classmethod find_module(fullname, path=None)¶
Метод класса, который пытается найти загрузчик для модуля, указанного в fullname, в sys.path или, если задан, в path. Для каждой записи пути, которая просматривается, sys.path_importer_cache проверяется. Если найден неложный объект, то он используется как finder для поиска модуля, который ищется. Если в sys.path_importer_cache ничего не найдено, то sys.path_hooks ищется на предмет finder для записи пути и, если найден, сохраняется в sys.path_importer_cache, а также выполняется запрос относительно модуля. Если ни один finder не найден, возвращается None.
29.6.5. importlib.util – Вспомогательный код для импортёров¶importlib.util – Utility code for importers
Этот модуль содержит различные объекты, помогающие в создании импортёра.
- @importlib.util.module_for_loader¶
Декоратор для метода загрузчика, чтобы выбрать подходящий объект модуля для загрузки. Декорированный метод должен иметь сигнатуру вызова с двумя позиционными аргументами (например, load_module(self, module)), где второй аргумент будет объектом модуля, который будет использоваться загрузчиком. Обратите внимание: декоратор не будет работать со статическими методами, так как предполагается два аргумента.
Декорированный метод будет принимать имя модуля для загрузки, как и ожидается для загрузчика. Если модуль не найден в sys.modules, то создаётся новый с установленным атрибутом __name__. В противном случае модуль, найденный в sys.modules, будет передан в метод. Если декорированный метод вызывает исключение и модуль был добавлен в sys.modules, он будет удалён, чтобы не оставлять частично инициализированный модуль в sys.modules. Если модуль уже был в sys.modules, он остаётся нетронутым.
Использование этого декоратора обрабатывает все детали того, какой объект модуля должен инициализировать загрузчик, как указано в PEP 302.
- @importlib.util.set_loader¶
Декоратор для метода загрузчика, который устанавливает атрибут __loader__ на загруженных модулях. Если атрибут уже установлен, декоратор ничего не делает. Предполагается, что первый позиционный аргумент обёрнутого метода – это то, на что должен быть установлен __loader__.
- @importlib.util.set_package¶
Декоратор декоратор для загрузчика, устанавливающий атрибут __package__ на модуле, возвращаемом загрузчиком. Если __package__ уже установлен и имеет значение, отличное от None, он не будет изменён. Обратите внимание, что атрибут устанавливается на модуле, возвращаемом загрузчиком, а не на модуле, найденном в sys.modules.
Полагаться на этот декоратор не рекомендуется, когда есть возможность установить __package__ до начала выполнения кода. Устанавливая его до выполнения кода модуля, этот атрибут можно использовать на глобальном уровне модуля во время инициализации.