importlib
— Реализация import
¶
Added in version 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
Тип ModuleSpec для системы импорта
- PEP 488
Ликвидация файлов PYO
- PEP 489
Многофазная инициализация модуля расширения
- PEP 552
Детерминированные пики
- PEP 3120
Использование UTF-8 в качестве кодировки источника по умолчанию
- PEP 3147
Справочники репозиториев PYC
Функции¶
- importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)¶
Реализация встроенной функции
__import__()
.Примечание
При программном импорте модулей вместо этой функции следует использовать
import_module()
.
- importlib.import_module(name, package=None)¶
Импортировать модуль. Аргумент name указывает, какой модуль импортировать в абсолютном или относительном выражении (например, либо
pkg.mod
, либо..mod
). Если имя указано в относительном выражении, то аргумент package должен быть установлен в имя пакета, который будет выступать в качестве якоря для разрешения имени пакета (например,import_module('..mod', 'pkg.subpkg')
импортируетpkg.mod
).Функция
import_module()
действует как упрощающая обертка вокругimportlib.__import__()
. Это означает, что вся семантика этой функции вытекает изimportlib.__import__()
. Самое важное различие между этими двумя функциями заключается в том, чтоimport_module()
возвращает указанный пакет или модуль (например,pkg.mod
), а__import__()
возвращает пакет или модуль верхнего уровня (например,pkg
).Если вы динамически импортируете модуль, который был создан после того, как интерпретатор начал выполнение (например, создал исходный файл Python), вам может понадобиться вызвать
invalidate_caches()
, чтобы новый модуль был замечен системой импорта.Изменено в версии 3.3: Родительские пакеты импортируются автоматически.
- importlib.invalidate_caches()¶
Аннулирует внутренние кэши искателей, хранящиеся по адресу
sys.meta_path
. Если finder реализуетinvalidate_caches()
, то будет вызвана эта функция для выполнения аннулирования. Эту функцию следует вызывать, если во время работы программы создаются/устанавливаются какие-либо модули, чтобы гарантировать, что все искатели заметят существование нового модуля.Added in version 3.3.
Изменено в версии 3.10: Замечены пакеты пространства имен, созданные/установленные в другом месте
sys.path
после того, как одно и то же пространство имен уже было импортировано.
- importlib.reload(module)¶
Перезагрузить ранее импортированный модуль. Аргумент должен быть объектом модуля, поэтому он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля с помощью внешнего редактора и хотите опробовать новую версию, не выходя из интерпретатора Python. Возвращаемое значение - объект модуля (который может быть другим, если при повторном импорте в
sys.modules
будет помещен другой объект).Когда выполняется
reload()
:Код модуля Python перекомпилируется и код на уровне модуля выполняется заново, определяя новый набор объектов, которые привязываются к именам в словаре модуля, повторно используя loader, которая первоначально загрузила модуль. Функция
init
модулей расширения второй раз не вызывается.Как и все остальные объекты в Python, старые объекты восстанавливаются только после того, как количество их ссылок упадет до нуля.
Имена в пространстве имен модуля обновляются, чтобы указать на все новые или измененные объекты.
Другие ссылки на старые объекты (например, имена, внешние по отношению к модулю) не могут ссылаться на новые объекты и должны быть обновлены в каждом пространстве имен, где они встречаются, если это необходимо.
Есть и ряд других предостережений:
Когда модуль перезагружается, его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределения имен отменяют старые определения, так что это, как правило, не является проблемой. Если в новой версии модуля не определено имя, которое было определено в старой версии, старое определение сохраняется. Эта возможность может быть использована с пользой для модуля, если он поддерживает глобальную таблицу или кэш объектов - с помощью оператора
try
можно проверить наличие таблицы и при желании пропустить ее инициализацию:try: cache except NameError: cache = {}
Перезагружать встроенные или динамически загружаемые модули, как правило, не очень полезно. Не рекомендуется перезагружать
sys
,__main__
,builtins
и другие ключевые модули. Во многих случаях модули расширения не предназначены для инициализации более одного раза и при перезагрузке могут дать произвольный сбой.Если модуль импортирует объекты из другого модуля с помощью
from
…import
…, вызовreload()
для другого модуля не переопределяет импортированные из него объекты - один из способов обойти это заключается в повторном выполнении оператораfrom
, другой - в использованииimport
и квалифицированных имен (module.name) вместо этого.Если модуль инстанцирует экземпляры класса, перезагрузка модуля, определяющего класс, не влияет на определения методов экземпляров - они продолжают использовать старое определение класса. То же самое справедливо и для производных классов.
Added in version 3.4.
Изменено в версии 3.7:
ModuleNotFoundError
возникает, если в перезагружаемом модуле отсутствуетModuleSpec
.
importlib.abc
– Абстрактные базовые классы, связанные с импортом¶
Источник: Lib/importlib/abc.py
Модуль importlib.abc
содержит все основные абстрактные базовые классы, используемые в import
. Некоторые подклассы основных абстрактных базовых классов также предоставляются для помощи в реализации основных ABC.
Иерархия ABC:
object
+-- MetaPathFinder
+-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- class importlib.abc.MetaPathFinder¶
Абстрактный базовый класс, представляющий meta path finder.
Added in version 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder
.- find_spec(fullname, path, target=None)¶
Абстрактный метод для поиска spec для указанного модуля. Если это импорт верхнего уровня, то path будет значением
None
. В противном случае, это поиск подпакета или модуля, и path будет значением__path__
из родительского пакета. Если спецификация не найдена, возвращаетсяNone
. При передачеtarget
- это объект модуля, который может быть использован искателем для более точного определения того, какую спецификацию следует вернуть.importlib.util.spec_from_loader()
может быть полезен для реализации конкретныхMetaPathFinders
.Added in version 3.4.
- invalidate_caches()¶
Необязательный метод, который при вызове должен аннулировать любой внутренний кэш, используемый искателем. Используется
importlib.invalidate_caches()
при аннулировании кэшей всех искателей наsys.meta_path
.Изменено в версии 3.4: Возвращает
None
при вызове вместоNotImplemented
.
- class importlib.abc.PathEntryFinder¶
Абстрактный базовый класс, представляющий path entry finder. Хотя он имеет некоторое сходство с
MetaPathFinder
,PathEntryFinder
предназначен для использования только в рамках подсистемы импорта на основе путей, предоставляемойimportlib.machinery.PathFinder
.Added in version 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder
.- find_spec(fullname, target=None)¶
Абстрактный метод для поиска spec для указанного модуля. Метод будет искать модуль только в пределах path entry, которому он назначен. Если модуль не найден, возвращается
None
. При передачеtarget
- это объект модуля, который finder может использовать для более обоснованного предположения о том, какую спецификацию вернуть.importlib.util.spec_from_loader()
может быть полезен для реализации конкретныхPathEntryFinders
.Added in version 3.4.
- invalidate_caches()¶
Необязательный метод, который при вызове должен аннулировать любой внутренний кэш, используемый искателем. Используется
importlib.machinery.PathFinder.invalidate_caches()
при аннулировании кэшей всех кэшированных искателей.
- class importlib.abc.Loader¶
Абстрактный базовый класс для loader. Точное определение загрузчика см. в разделе PEP 302.
Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать метод
get_resource_reader()
, как указано вimportlib.resources.abc.ResourceReader
.Изменено в версии 3.7: Введен необязательный метод
get_resource_reader()
.- create_module(spec)¶
Метод, возвращающий объект модуля, который следует использовать при импорте модуля. Этот метод может возвращать
None
, указывая на то, что должна использоваться семантика создания модуля по умолчанию.Added in version 3.4.
Изменено в версии 3.6: Этот метод больше не является необязательным, если определена
exec_module()
.
- exec_module(module)¶
Абстрактный метод, который выполняет модуль в его собственном пространстве имен, когда модуль импортируется или перезагружается. При вызове
exec_module()
модуль уже должен быть инициализирован. Когда этот метод существует, должен быть определенcreate_module()
.Added in version 3.4.
Изменено в версии 3.6:
create_module()
также должен быть определен.
- load_module(fullname)¶
Унаследованный метод для загрузки модуля. Если модуль не может быть загружен, вызывается сообщение
ImportError
, в противном случае возвращается загруженный модуль.Если запрашиваемый модуль уже существует в
sys.modules
, он должен быть использован и перезагружен. В противном случае загрузчик должен создать новый модуль и вставить его вsys.modules
до начала загрузки, чтобы предотвратить рекурсию при импорте. Если загрузчик вставил модуль и загрузка не удалась, он должен удалить его изsys.modules
; модули, уже находившиеся вsys.modules
до начала выполнения загрузчика, должны быть оставлены в покое.Загрузчик должен установить несколько атрибутов модуля (обратите внимание, что некоторые из этих атрибутов могут меняться при перезагрузке модуля):
__name__
Полное квалифицированное имя модуля. Для выполненного модуля оно равно
'__main__'
.
__cached__
Имя файла скомпилированной версии кода модуля. Устанавливается не для всех модулей (например, встроенных).
__path__
Список мест, где будут находиться подмодули пакета. Чаще всего это один каталог. Система импорта передает этот атрибут в
__import__()
и в finders так же, как и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()
.
- class importlib.abc.ResourceLoader¶
Абстрактный базовый класс для loader, который реализует дополнительный протокол PEP 302 для загрузки произвольных ресурсов из внутреннего хранилища.
Не рекомендуется, начиная с версии 3.7: Этот ABC устарел в пользу поддержки загрузки ресурсов через
importlib.resources.abc.ResourceReader
.- abstractmethod get_data(path)¶
Абстрактный метод, возвращающий байты для данных, расположенных по адресу path. Загрузчики, имеющие файлоподобное хранилище, позволяющее хранить произвольные данные, могут реализовать этот абстрактный метод для прямого доступа к хранимым данным. Если путь не может быть найден, вызывается сообщение
OSError
. Ожидается, что путь будет создан с помощью атрибута__file__
модуля или элемента из__path__
пакета.Изменено в версии 3.4: Поднимает
OSError
вместоNotImplementedError
.
- class importlib.abc.InspectLoader¶
Абстрактный базовый класс для loader, который реализует дополнительный протокол PEP 302 для загрузчиков, проверяющих модули.
- get_code(fullname)¶
Возвращает объект кода для модуля или
None
, если у модуля нет объекта кода (как, например, у встроенного модуля). Вызывает сообщениеImportError
, если загрузчик не может найти запрашиваемый модуль.Примечание
Хотя метод имеет реализацию по умолчанию, рекомендуется переопределить его, если это возможно для повышения производительности.
Изменено в версии 3.4: Больше не является абстрактным и предоставляет конкретную реализацию.
- abstractmethod get_source(fullname)¶
Абстрактный метод для возврата исходного текста модуля. Он возвращается в виде текстовой строки с использованием universal newlines, переводя все распознанные разделители строк в символы
'\n'
. ВозвращаетNone
, если источник недоступен (например, встроенный модуль). ВозвращаетImportError
, если загрузчик не может найти указанный модуль.Изменено в версии 3.4: Поднимает
ImportError
вместоNotImplementedError
.
- is_package(fullname)¶
Необязательный метод, возвращающий значение true, если модуль является пакетом, и false в противном случае. Значение
ImportError
возвращается, если loader не может найти модуль.Изменено в версии 3.4: Поднимает
ImportError
вместоNotImplementedError
.
- static source_to_code(data, path='<string>')¶
Создайте объект кода из источника Python.
Аргумент data может быть любым, который поддерживает функция
compile()
(например, строка или байт). Аргумент path должен быть «путем» к месту, откуда взят исходный код, который может быть абстрактным понятием (например, расположение в zip-файле).С последующим кодовым объектом можно выполнить его в модуле, запустив
exec(code, module.__dict__)
.Added in version 3.4.
Изменено в версии 3.5: Сделал метод статическим.
- exec_module(module)¶
Реализация
Loader.exec_module()
.Added in version 3.4.
- load_module(fullname)¶
Реализация
Loader.load_module()
.Не рекомендуется, начиная с версии 3.4: используйте вместо этого
exec_module()
.
- class importlib.abc.ExecutionLoader¶
Абстрактный базовый класс, наследуемый от
InspectLoader
, который, будучи реализованным, помогает модулю выполняться как скрипт. ABC представляет необязательный протокол PEP 302.- abstractmethod get_filename(fullname)¶
Абстрактный метод, который должен возвращать значение
__file__
для указанного модуля. Если путь недоступен, возвращается значениеImportError
.Если исходный код доступен, то метод должен вернуть путь к исходному файлу, независимо от того, использовался ли байткод для загрузки модуля.
Изменено в версии 3.4: Поднимает
ImportError
вместоNotImplementedError
.
- class importlib.abc.FileLoader(fullname, path)¶
Абстрактный базовый класс, который наследуется от
ResourceLoader
иExecutionLoader
, предоставляя конкретные реализацииResourceLoader.get_data()
иExecutionLoader.get_filename()
.Аргумент fullname - это полностью разрешенное имя модуля, с которым должен работать загрузчик. Аргумент path - это путь к файлу с модулем.
Added in version 3.3.
- name¶
Имя модуля, с которым может работать загрузчик.
- path¶
Путь к файлу модуля.
- load_module(fullname)¶
Вызывает супер
load_module()
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
Loader.exec_module()
.
- abstractmethod get_data(path)¶
Считывает path как двоичный файл и возвращает байты из него.
- class importlib.abc.SourceLoader¶
Абстрактный базовый класс для реализации загрузки исходных файлов (и, опционально, байткода). Класс наследуется от
ResourceLoader
иExecutionLoader
, требуя реализации:ExecutionLoader.get_filename()
Должен возвращать только путь к исходному файлу; загрузка без источника не поддерживается.
Абстрактные методы, определенные этим классом, предназначены для добавления необязательной поддержки файлов байткода. Если не реализовать эти необязательные методы (или заставить их вызывать
NotImplementedError
), загрузчик будет работать только с исходным кодом. Реализация этих методов позволяет загрузчику работать с файлами исходного кода и байткода; она не позволяет загружать без источника, где предоставляется только байткод. Файлы байткода - это оптимизация для ускорения загрузки за счет удаления этапа разбора компилятора Python, поэтому API, специфичный для байткода, не предоставляется.- path_stats(path)¶
Необязательный абстрактный метод, возвращающий
dict
, содержащий метаданные об указанном пути. Поддерживаются следующие ключи словаря:'mtime'
(обязательно): целое число или число с плавающей точкой, представляющее время модификации исходного кода;'size'
(необязательно): размер исходного кода в байтах.
Любые другие ключи в словаре игнорируются, чтобы обеспечить возможность будущих расширений. Если путь не может быть обработан, выдается сообщение
OSError
.Added in version 3.3.
Изменено в версии 3.4: Поднимите
OSError
вместоNotImplementedError
.
- path_mtime(path)¶
Необязательный абстрактный метод, возвращающий время модификации для указанного пути.
Не рекомендуется, начиная с версии 3.3: Этот метод устарел в пользу
path_stats()
. Вы не обязаны его реализовывать, но он по-прежнему доступен для совместимости. ВызываетOSError
, если путь не может быть обработан.Изменено в версии 3.4: Поднимите
OSError
вместоNotImplementedError
.
- set_data(path, data)¶
Необязательный абстрактный метод, который записывает указанные байты в файл по пути. Все несуществующие промежуточные каталоги будут созданы автоматически.
Если запись в путь не удается, потому что путь доступен только для чтения (
errno.EACCES
/PermissionError
), не распространяйте исключение.Изменено в версии 3.4: Больше не поднимает
NotImplementedError
при вызове.
- get_code(fullname)¶
Конкретная реализация
InspectLoader.get_code()
.
- exec_module(module)¶
Конкретная реализация
Loader.exec_module()
.Added in version 3.4.
- load_module(fullname)¶
Конкретная реализация
Loader.load_module()
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
exec_module()
.
- get_source(fullname)¶
Конкретная реализация
InspectLoader.get_source()
.
- is_package(fullname)¶
Конкретная реализация
InspectLoader.is_package()
. Модуль считается пакетом, если путь к его файлу (как указано вExecutionLoader.get_filename()
) представляет собой файл с именем__init__
, если удалить расширение файла и само имя модуля не заканчивается на__init__
.
- class importlib.abc.ResourceReader¶
Заменено на TraversableResources.
Значение abstract base class, обеспечивающее возможность чтения ресурсов.
С точки зрения этого букваря, ресурс - это двоичный артефакт, который поставляется в составе пакета. Обычно это что-то вроде файла данных, который находится рядом с
__init__.py
файлом пакета. Цель этого класса - помочь абстрагироваться от доступа к таким файлам данных, чтобы не имело значения, хранится ли пакет и его файл(ы) данных в файле zip, а не в файловой системе.Для любого из методов этого класса аргумент resource должен быть path-like object, который концептуально представляет собой просто имя файла. Это означает, что в аргумент resource не должны включаться пути к подкаталогам. Это происходит потому, что в качестве «каталога» выступает местоположение пакета, для которого предназначен считыватель. Отсюда метафора для каталогов и имен файлов - пакеты и ресурсы, соответственно. Именно поэтому ожидается, что экземпляры этого класса будут напрямую соотноситься с конкретным пакетом (вместо того, чтобы потенциально представлять несколько пакетов или модуль).
Загрузчики, которые хотят поддерживать чтение ресурсов, должны предоставлять метод
get_resource_reader(fullname)
, который возвращает объект, реализующий интерфейс этого ABC. Если модуль, указанный в fullname, не является пакетом, этот метод должен возвращатьNone
. Объект, совместимый с данным ABC, должен возвращаться только в том случае, если указанный модуль является пакетом.Added in version 3.7.
Утратил актуальность с версии 3.12, удален в версии 3.14: Вместо этого используйте
importlib.resources.abc.TraversableResources
.- abstractmethod open_resource(resource)¶
Возвращает открытое значение, file-like object для бинарного чтения ресурса.
Если ресурс не может быть найден, выдается сообщение
FileNotFoundError
.
- abstractmethod resource_path(resource)¶
Возвращает путь файловой системы к ресурсу.
Если ресурс конкретно не существует в файловой системе, поднимите
FileNotFoundError
.
- abstractmethod is_resource(name)¶
Возвращает
True
, если имя name считается ресурсом. ВозвращаетсяFileNotFoundError
, если имя name не существует.
- abstractmethod contents()¶
Возвращает iterable строк над содержимым пакета. Обратите внимание, что не обязательно, чтобы все имена, возвращаемые итератором, были реальными ресурсами, например, допустимо возвращать имена, для которых
is_resource()
будет ложным.Разрешение возвращать имена, не относящиеся к ресурсам, необходимо для ситуаций, когда способ хранения пакета и его ресурсов известен априори и имена, не относящиеся к ресурсам, могут быть полезны. Например, возврат имен подкаталогов разрешен для того, чтобы, когда известно, что пакет и ресурсы хранятся в файловой системе, можно было напрямую использовать имена этих подкаталогов.
Абстрактный метод возвращает итерабельную таблицу, не содержащую элементов.
- class importlib.abc.Traversable¶
Объект с подмножеством методов
pathlib.Path
, подходящих для обхода каталогов и открытия файлов.Для представления объекта в файловой системе используйте
importlib.resources.as_file()
.Added in version 3.9.
Утратил актуальность с версии 3.12, удален в версии 3.14: Вместо этого используйте
importlib.resources.abc.Traversable
.- name¶
Абстрактное. Базовое имя этого объекта без каких-либо родительских ссылок.
- abstractmethod iterdir()¶
Добывайте
Traversable
объектов вself
.
- abstractmethod is_dir()¶
Верните
True
, еслиself
является каталогом.
- abstractmethod is_file()¶
Верните
True
, еслиself
- это файл.
- abstractmethod joinpath(child)¶
Возвращает обходной ребенок в
self
.
- abstractmethod __truediv__(child)¶
Верните
Traversable
ребенка вself
.
- abstractmethod open(mode='r', *args, **kwargs)¶
mode может быть „r“ или „rb“ для открытия в текстовом или двоичном виде. Возвращает хэндл, пригодный для чтения (то же, что и
pathlib.Path.open
).При открытии в виде текста принимает параметры кодировки, подобные тем, что принимает
io.TextIOWrapper
.
- read_bytes()¶
Считывание содержимого
self
в виде байтов.
- read_text(encoding=None)¶
Прочитайте содержимое
self
как текст.
- class importlib.abc.TraversableResources¶
Абстрактный базовый класс для считывателей ресурсов, способных обслуживать интерфейс
importlib.resources.files()
. Является подклассомimportlib.resources.abc.ResourceReader
и предоставляет конкретные реализации абстрактных методовimportlib.resources.abc.ResourceReader
. Поэтому любой загрузчик, поставляющийimportlib.abc.TraversableResources
, также поставляет ResourceReader.Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать этот интерфейс.
Added in version 3.9.
Утратил актуальность с версии 3.12, удален в версии 3.14: Вместо этого используйте
importlib.resources.abc.TraversableResources
.- abstractmethod files()¶
Возвращает объект
importlib.resources.abc.Traversable
для загруженного пакета.
importlib.machinery
– Импортеры и крючки путей¶
Источник: Lib/importlib/machinery.py
Этот модуль содержит различные объекты, которые помогают import
находить и загружать модули.
- importlib.machinery.SOURCE_SUFFIXES¶
Список строк, представляющих распознанные суффиксы файлов для исходных модулей.
Added in version 3.3.
- importlib.machinery.DEBUG_BYTECODE_SUFFIXES¶
Список строк, представляющих суффиксы файлов для неоптимизированных модулей байткода.
Added in version 3.3.
Не рекомендуется, начиная с версии 3.5: Вместо этого используйте
BYTECODE_SUFFIXES
.
- importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES¶
Список строк, представляющих суффиксы файлов для оптимизированных модулей байткода.
Added in version 3.3.
Не рекомендуется, начиная с версии 3.5: Вместо этого используйте
BYTECODE_SUFFIXES
.
- importlib.machinery.BYTECODE_SUFFIXES¶
Список строк, представляющих распознанные суффиксы файлов для модулей байткода (включая ведущую точку).
Added in version 3.3.
Изменено в версии 3.5: Значение больше не зависит от
__debug__
.
- importlib.machinery.EXTENSION_SUFFIXES¶
Список строк, представляющих распознанные суффиксы файлов для модулей расширения.
Added in version 3.3.
- importlib.machinery.all_suffixes()¶
Возвращает объединенный список строк, представляющих все суффиксы файлов для модулей, распознаваемых стандартным механизмом импорта. Это помощник для кода, которому просто нужно знать, ссылается ли путь к файловой системе на модуль, не требуя подробностей о типе модуля (например,
inspect.getmodulename()
).Added in version 3.3.
- class importlib.machinery.BuiltinImporter¶
importer для встроенных модулей. Все известные встроенные модули перечислены в
sys.builtin_module_names
. Этот класс реализуетimportlib.abc.MetaPathFinder
иimportlib.abc.InspectLoader
ABC.В этом классе определяются только методы класса, чтобы избежать необходимости инстанцирования.
Изменено в версии 3.5: В рамках PEP 489 встроенный импортер теперь реализует
Loader.create_module()
иLoader.exec_module()
.
- class importlib.machinery.FrozenImporter¶
Класс importer для замороженных модулей. Этот класс реализует
importlib.abc.MetaPathFinder
иimportlib.abc.InspectLoader
. ABC.В этом классе определяются только методы класса, чтобы избежать необходимости инстанцирования.
Изменено в версии 3.4: Получил методы
create_module()
иexec_module()
.
- class importlib.machinery.WindowsRegistryFinder¶
Finder для модулей, объявленных в реестре Windows. Этот класс реализует
importlib.abc.MetaPathFinder
ABC.В этом классе определяются только методы класса, чтобы избежать необходимости инстанцирования.
Added in version 3.3.
Не рекомендуется, начиная с версии 3.6: Вместо этого используйте конфигурацию
site
. Будущие версии Python могут не включать этот поисковик по умолчанию.
- class importlib.machinery.PathFinder¶
Класс Finder для атрибутов
sys.path
и пакета__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
и сохраняется в кэше, и возвращается.Added in version 3.4.
Изменено в версии 3.5: Если текущий рабочий каталог - представленный пустой строкой - больше не действителен, то возвращается
None
, но вsys.path_importer_cache
значение не кэшируется.
- classmethod invalidate_caches()¶
Вызывает
importlib.abc.PathEntryFinder.invalidate_caches()
для всех хранящихся вsys.path_importer_cache
искателей, которые определяют метод. В противном случае записи вsys.path_importer_cache
, установленные вNone
, удаляются.Изменено в версии 3.7: Записи
None
вsys.path_importer_cache
удаляются.
Изменено в версии 3.4: Вызывает объекты в
sys.path_hooks
с текущим рабочим каталогом для''
(т.е. пустой строкой).
- class importlib.machinery.FileFinder(path, *loader_details)¶
Конкретная реализация
importlib.abc.PathEntryFinder
, которая кэширует результаты из файловой системы.Аргумент path - это директория, в которой будет производиться поиск.
Аргумент loader_details представляет собой переменное количество кортежей из двух элементов, каждый из которых содержит загрузчик и последовательность суффиксов файлов, которые распознает загрузчик. Предполагается, что загрузчики являются вызываемыми файлами, которые принимают два аргумента: имя модуля и путь к найденному файлу.
Программа поиска будет кэшировать содержимое каталога по мере необходимости, выполняя вызовы stat при каждом поиске модуля, чтобы убедиться, что кэш не устарел. Поскольку устойчивость кэша зависит от детализации информации операционной системы о состоянии файловой системы, существует потенциальное состояние гонки: поиск модуля, создание нового файла, а затем поиск модуля, который представляет новый файл. Если эти операции выполняются достаточно быстро, чтобы уложиться в гранулярность вызовов stat, то поиск модуля завершится неудачей. Чтобы этого не произошло, при динамическом создании модуля обязательно вызывайте
importlib.invalidate_caches()
.Added in version 3.3.
- path¶
Путь, по которому будет вестись поиск.
- find_spec(fullname, target=None)¶
Попытка найти спецификацию для обработки fullname в пределах
path
.Added in version 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
и предоставления некоторых конкретных реализаций других методов.Added in version 3.3.
- name¶
Имя модуля, который будет обрабатывать этот загрузчик.
- path¶
Путь к исходному файлу.
- path_stats(path)¶
Конкретная реализация
importlib.abc.SourceLoader.path_stats()
.
- set_data(path, data)¶
Конкретная реализация
importlib.abc.SourceLoader.set_data()
.
- load_module(name=None)¶
Конкретная реализация
importlib.abc.Loader.load_module()
, в которой указание имени загружаемого модуля необязательно.Не рекомендуется, начиная с версии 3.6: Вместо этого используйте
importlib.abc.Loader.exec_module()
.
- class importlib.machinery.SourcelessFileLoader(fullname, path)¶
Конкретная реализация
importlib.abc.FileLoader
, которая может импортировать файлы байткода (т.е. файлы исходного кода отсутствуют).Обратите внимание, что прямое использование файлов байткода (а не файлов исходного кода) препятствует использованию ваших модулей всеми реализациями Python или новыми версиями Python, изменяющими формат байткода.
Added in version 3.3.
- name¶
Имя модуля, с которым будет работать загрузчик.
- path¶
Путь к файлу байткода.
- 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 - это путь к файлу модуля расширения.
Обратите внимание, что по умолчанию импорт модуля расширения будет неудачным в субинтерпретаторах, если он не реализует многофазную инициализацию (см. PEP 489), даже если в противном случае импорт пройдет успешно.
Added in version 3.3.
Изменено в версии 3.12: Для использования в субинтерпретаторах теперь требуется многофазный init.
- name¶
Имя модуля, который поддерживает загрузчик.
- path¶
Путь к модулю расширения.
- create_module(spec)¶
Создает объект модуля из заданной спецификации в соответствии с PEP 489.
Added in version 3.5.
- exec_module(module)¶
Инициализирует заданный объект модуля в соответствии с PEP 489.
Added in version 3.5.
- is_package(fullname)¶
Возвращает
True
, если путь к файлу указывает на модуль__init__
пакета, основанный наEXTENSION_SUFFIXES
.
- get_code(fullname)¶
Возвращает
None
, так как у модулей расширения отсутствует объект кода.
- get_source(fullname)¶
Возвращает
None
, так как модули расширения не имеют исходного кода.
- 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
Added in version 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
модуля, и наоборот.Added in version 3.4.
- name¶
(
__name__
)Полное имя модуля. В finder этот атрибут всегда должен быть установлен в непустую строку.
- loader¶
Атрибут loader, используемый для загрузки модуля. Атрибут finder должен быть установлен всегда.
- origin¶
(
__file__
)Место, которое loader должен использовать loader для загрузки модуля. Например, для модулей, загружаемых из файла .py, это имя файла. Атрибут finder должен всегда устанавливать это значение, чтобы loader мог его использовать. В редких случаях, когда такого значения нет (например, для пакетов пространства имен), оно должно быть установлено в
None
.- submodule_search_locations¶
(
__path__
)Список мест, где будут находиться подмодули пакета. Чаще всего это один каталог. Атрибут finder должен устанавливать этот атрибут в список, даже пустой, чтобы указать системе импорта, что модуль является пакетом. Для непакетных модулей он должен быть установлен в
None
. Позже он автоматически устанавливается в специальный объект для пакетов пространства имен.- loader_state¶
Атрибут finder может быть установлен в объект, содержащий дополнительные, специфические для модуля данные, которые будут использоваться при загрузке модуля. В противном случае он должен быть установлен в
None
.- cached¶
Имя файла скомпилированной версии кода модуля. Этот атрибут всегда должен быть установлен finder, но может быть
None
для модулей, которым не нужно хранить скомпилированный код.- parent¶
(Только для чтения) Полное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же самое, что и
name
.- has_location¶
- class importlib.machinery.AppleFrameworkLoader(name, path)¶
Специализация
importlib.machinery.ExtensionFileLoader
, способная загружать модули расширения в формате Framework.Для совместимости с iOS App Store все двоичные модули в приложении для iOS должны быть динамическими библиотеками, содержащимися во фреймворке с соответствующими метаданными, который хранится в папке
Frameworks
упакованного приложения. Для каждого фреймворка может быть только один двоичный файл, и не может быть исполняемого двоичного материала вне папки Frameworks.Чтобы удовлетворить это требование, при работе на iOS двоичные файлы модулей расширения не упаковываются как файлы
.so
наsys.path
, а как отдельные автономные фреймворки. Чтобы обнаружить эти фреймворки, данный загрузчик регистрируется в расширении.fwork
, а файл.fwork
выступает в качестве держателя исходного местоположения бинарного файла наsys.path
. Файл.fwork
содержит путь к реальному двоичному файлу в папкеFrameworks
относительно пакета приложений. Чтобы разрешить возврат бинарных файлов, упакованных фреймворком, в исходное местоположение, фреймворк должен содержать файл.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
(создавая имя фреймворка из полного пути импорта модуля), с файломInfo.plist
в каталоге.framework
, идентифицирующим бинарник как фреймворк. Модульfoo.bar._whiz
будет представлен в исходном расположении с помощью файла-маркераsources/foo/bar/_whiz.abi3.fwork
, содержащего путьFrameworks/foo.bar._whiz/foo.bar._whiz
. Фреймворк также будет содержатьFrameworks/foo.bar._whiz.framework/foo.bar._whiz.origin
, содержащий путь к файлу.fwork
.Когда модуль загружается с помощью этого загрузчика,
__file__
модуля будет отображаться как расположение.fwork
файла. Это позволяет коду использовать__file__
модуля в качестве привязки для обхода файловой системы. Однако спецификация будет ссылаться на расположение фактического бинарного файла в папке.framework
.Проект Xcode, собирающий приложение, отвечает за преобразование любых файлов
.so
из папкиPYTHONPATH
в папкуFrameworks
(включая удаление расширений из файла модуля, добавление метаданных фреймворка и подписание полученного фреймворка), а также за создание файлов.fwork
и.origin
. Обычно это делается с помощью шага сборки в проекте Xcode; подробности о том, как создать этот шаг сборки, см. в документации по iOS.Added in version 3.13.
Availability: iOS.
- name¶
Имя модуля, который поддерживает загрузчик.
- path¶
Путь к
.fwork
файлу для модуля расширения.
importlib.util
– Код утилиты для импортеров¶
Источник: Lib/importlib/util.py
Этот модуль содержит различные объекты, которые помогают в построении importer.
- importlib.util.MAGIC_NUMBER¶
Байт, представляющий номер версии байткода. Если вам нужна помощь в загрузке/записи байткода, рассмотрите вариант
importlib.abc.SourceLoader
.Added in version 3.4.
- importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)¶
Возвращает путь PEP 3147/PEP 488 к байт-компилированному файлу, связанному с источником path. Например, если path - это
/foo/bar/baz.py
, то для Python 3.2 возвращаемое значение будет/foo/bar/__pycache__/baz.cpython-32.pyc
. Строкаcpython-32
берется из текущего магического тега (см.get_tag()
; еслиsys.implementation.cache_tag
не определен, то будет заданNotImplementedError
).Параметр оптимизация используется для указания уровня оптимизации файла байткода. Пустая строка означает отсутствие оптимизации, поэтому
/foo/bar/baz.py
с оптимизацией, равной''
, приведет к пути к байткоду, равному/foo/bar/__pycache__/baz.cpython-32.pyc
.None
приводит к использованию уровня оптимизации интерпретатора. Любое другое значение используется в строковом представлении, поэтому/foo/bar/baz.py
с оптимизацией2
приведет к пути байткода/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc
. Строковое представление оптимизации может быть только буквенно-цифровым, в противном случае будет выдано сообщениеValueError
.Параметр debug_override является устаревшим и может быть использован для переопределения значения
__debug__
, установленного системой. ЗначениеTrue
эквивалентно установке оптимизации в пустую строку. ЗначениеFalse
равнозначно установке оптимизации в1
. Если оба значения debug_override и optimization не равныNone
, то возникает ошибкаTypeError
.Added in version 3.4.
Изменено в версии 3.5: Был добавлен параметр optimization, а параметр debug_override был устаревшим.
Изменено в версии 3.6: Принимает path-like object.
- importlib.util.source_from_cache(path)¶
Если задан путь к имени файла PEP 3147, то возвращается путь к соответствующему файлу исходного кода. Например, если path - это
/foo/bar/__pycache__/baz.cpython-32.pyc
, то возвращаемый путь будет/foo/bar/baz.py
. Путь path не обязательно должен существовать, однако если он не соответствует формату PEP 3147 или PEP 488, возникает ошибкаValueError
. Еслиsys.implementation.cache_tag
не определен, возникает ошибкаNotImplementedError
.Added in version 3.4.
Изменено в версии 3.6: Принимает path-like object.
- importlib.util.decode_source(source_bytes)¶
Декодирует заданные байты, представляющие исходный код, и возвращает их в виде строки с универсальными новыми строками (как того требует
importlib.abc.InspectLoader.get_source()
).Added in version 3.4.
- importlib.util.resolve_name(name, package)¶
Преобразование относительного имени модуля в абсолютное.
Если name не содержит ведущих точек, то просто возвращается name. Это позволяет использовать, например,
importlib.util.resolve_name('sys', __spec__.parent)
, не проверяя, нужен ли аргумент package.ImportError
возникает, если name - относительное имя модуля, а package - ложное значение (например,None
или пустая строка).ImportError
также будет поднята, если относительное имя будет исключать содержащий его пакет (например, запрос..bacon
из пакетаspam
).Added in version 3.3.
Изменено в версии 3.9: Чтобы улучшить согласованность с заявлениями об импорте, поднимайте
ImportError
вместоValueError
для недопустимых попыток относительного импорта.
- importlib.util.find_spec(name, package=None)¶
Находит spec для модуля, опционально относительно указанного имени package. Если модуль находится в
sys.modules
, то возвращаетсяsys.modules[name].__spec__
(если только спецификация не будетNone
или не задана, в этом случае возвращаетсяValueError
). В противном случае выполняется поиск с использованиемsys.meta_path
. Если спецификация не найдена, возвращаетсяNone
.Если name относится к подмодулю (содержит точку), то родительский модуль импортируется автоматически.
name и package работают так же, как и для
import_module()
.Added in version 3.4.
Изменено в версии 3.7: Вызывает
ModuleNotFoundError
вместоAttributeError
, если package на самом деле не является пакетом (т.е. не имеет атрибута__path__
).
- importlib.util.module_from_spec(spec)¶
Создайте новый модуль на основе spec и
spec.loader.create_module
.Если
spec.loader.create_module
не возвращаетNone
, то все ранее существовавшие атрибуты не будут сброшены. Также не будет вызваноAttributeError
, если оно сработает при обращении к spec или установке атрибута модуля.Эта функция предпочтительнее, чем использование
types.ModuleType
для создания нового модуля, поскольку spec используется для установки как можно большего количества контролируемых импортом атрибутов модуля.Added in version 3.5.
- importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)¶
Функция-фабрика для создания экземпляра
ModuleSpec
на основе загрузчика. Параметры имеют то же значение, что и для ModuleSpec. Функция использует доступные loader API, такие какInspectLoader.is_package()
, для заполнения недостающей информации в спецификации.Added in version 3.4.
- importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)¶
Фабричная функция для создания экземпляра
ModuleSpec
на основе пути к файлу. Недостающая информация будет восполнена в спецификации за счет использования API загрузчика и подразумевания того, что модуль будет основан на файлах.Added in version 3.4.
Изменено в версии 3.6: Принимает path-like object.
- importlib.util.source_hash(source_bytes)¶
Возвращает хэш source_bytes в виде байтов. Файл, основанный на хэше
.pyc
, вставляетsource_hash()
содержимого соответствующего исходного файла в свой заголовок.Added in version 3.7.
- importlib.util._incompatible_extension_module_restrictions(*, disable_check)¶
Менеджер контекста, который может временно пропустить проверку совместимости для модулей расширения. По умолчанию проверка включена и будет неудачной, если однофазный модуль init импортируется в подинтерпретатор. Она также будет неудачной для многофазного модуля init, который явно не поддерживает GIL для каждого интерпретатора, при импорте в интерпретатор с собственным GIL.
Обратите внимание, что эта функция предназначена для необычных случаев, которые, скорее всего, со временем исчезнут. Вполне вероятно, что это не то, что вы искали.
Вы можете получить тот же эффект, что и эта функция, реализовав базовый интерфейс многофазного init (PEP 489) и солгав о поддержке нескольких интерпретаторов (или per-interpreter GIL).
Предупреждение
Использование этой функции для отключения проверки может привести к неожиданному поведению и даже сбоям. Ее следует использовать только при разработке модуля расширения.
Added in version 3.12.
- class importlib.util.LazyLoader(loader)¶
Класс, который откладывает выполнение загрузчика модуля до тех пор, пока модуль не получит доступ к какому-либо атрибуту.
Этот класс единственно работает с загрузчиками, определяющими
exec_module()
, поскольку требуется контроль над тем, какой тип модуля используется для модуля. По тем же причинам методcreate_module()
загрузчика должен возвращатьNone
или тип, для которого его атрибут__class__
может быть изменен, а также не использовать slots. Наконец, модули, подменяющие объект, помещенный вsys.modules
, работать не будут, так как нет способа корректно заменить ссылки на модуль во всем интерпретаторе; при обнаружении такой подмены будет выдано сообщениеValueError
.Примечание
Для проектов, где время запуска критично, этот класс позволяет потенциально минимизировать затраты на загрузку модуля, если он никогда не используется. Для проектов, в которых время запуска не имеет большого значения, использование этого класса очень не рекомендуется из-за того, что сообщения об ошибках, созданные во время загрузки, будут отложены и, таким образом, появятся вне контекста.
Added in version 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
, чтобы потенциально создать искатель. Этот пример покажет вам, как зарегистрировать собственные импортеры, чтобы импорт использовал их (для создания собственного импортера читайте документацию по соответствующим классам, определенным в этом пакете):
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. Ниже приводится примерная реализация importlib.import_module()
:, которая помогает проиллюстрировать различные API, которые раскрывает importlib:
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