importlib
— Реализация import
¶
Добавлено в версии 3.1.
Исходный код: Lib/importlib/__init__.py
Вступление¶
Пакет importlib
предназначен для трех целей.
Один из них заключается в обеспечении реализации оператора import
(и, следовательно, функции __import__()
) в исходном коде Python. Это обеспечивает реализацию import
, которая переносима в любой интерпретатор Python. Это также обеспечивает реализацию, которую легче понять, чем реализацию на языке программирования, отличном от Python.
Во-вторых, в этом пакете представлены компоненты для реализации import
, что упрощает пользователям создание собственных пользовательских объектов (обычно называемых importer) для участия в процессе импорта.
В-третьих, пакет содержит модули, предоставляющие дополнительные функциональные возможности для управления различными аспектами пакетов Python:
importlib.metadata
предоставляет доступ к метаданным из сторонних дистрибутивов.importlib.resources
предоставляет процедуры для доступа к некодируемым «ресурсам» из пакетов Python.
См.также
- Оператор import
Ссылка на язык для инструкции
import
.- Packages specification
Оригинальная спецификация пакетов. С момента написания этого документа некоторые семантические изменения были внесены (например, перенаправление на основе
None
вsys.modules
).- Функция
__import__()
Оператор
import
является синтаксическим сахаром для этой функции.- Инициализация пути поиска модуля sys.path
Инициализация
sys.path
.- PEP 235
Импорт на платформах без учета регистра
- :pep:`263`Импорт на платформах без учета регистра
Определение кодировок исходного кода Python
- PEP 302
Новые крючки для импорта
- PEP 328
Импорт: Многострочный и абсолютный/относительный
- PEP 366
Основной модуль явного относительного импорта
- PEP 420
Неявные пакеты пространства имен
- PEP 451
Тип спецификации модуля для системы импорта
- PEP 488
Удаление PYO-файлов
- PEP 489
Инициализация многофазного модуля расширения
- PEP 552
Детерминированные показатели pycs
- PEP 3120
Использование UTF-8 в качестве исходной кодировки по умолчанию
- PEP 3147
Каталоги репозитория PYC
Функции¶
- importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)¶
Реализация встроенной функции
__import__()
.Примечание
При программном импорте модулей вместо этой функции следует использовать
import_module()
.
- importlib.import_module(name, package=None)¶
Импортируйте модуль. Аргумент name указывает, какой модуль следует импортировать в абсолютном или относительном выражении (например, либо
pkg.mod
, либо..mod
). Если имя указано в относительных терминах, то аргументу package должно быть присвоено имя пакета, которое должно выступать в качестве привязки для определения имени пакета (например,import_module('..mod', 'pkg.subpkg')
будет импортироватьpkg.mod
).Функция
import_module()
действует как упрощающая оболочка дляimportlib.__import__()
. Это означает, что вся семантика функции является производной отimportlib.__import__()
. Наиболее важное различие между этими двумя функциями заключается в том, чтоimport_module()
возвращает указанный пакет или модуль (например,pkg.mod
), в то время как__import__()
возвращает пакет или модуль верхнего уровня (например,pkg
)..Если вы динамически импортируете модуль, который был создан с момента запуска интерпретатора (например, создали исходный файл Python), вам может потребоваться вызвать
invalidate_caches()
, чтобы система импорта заметила новый модуль.Изменено в версии 3.3: Родительские пакеты импортируются автоматически.
- importlib.find_loader(name, path=None)¶
Найдите загрузчик для модуля, необязательно в пределах указанного пути. Если модуль находится в
sys.modules
, то возвращаетсяsys.modules[name].__loader__
(если только загрузчик не будетNone
или не задан, и в этом случае вызываетсяValueError
). В противном случае выполняется поиск с использованиемsys.meta_path
.None
возвращается, если загрузчик не найден.Родительские элементы, обозначенные пунктиром, не импортируются неявным образом, поскольку для этого требуется их загрузка, а это может быть нежелательно. Чтобы правильно импортировать подмодуль, вам нужно импортировать все родительские пакеты подмодуля и использовать правильный аргумент path.
Добавлено в версии 3.3.
Изменено в версии 3.4: Если
__loader__
не задано, поднимите значениеValueError
, точно так же, как если бы для атрибута было установлено значениеNone
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
importlib.util.find_spec()
.
- importlib.invalidate_caches()¶
Аннулировать внутренние кэши средств поиска, хранящиеся в
sys.meta_path
. Если средство поиска реализуетinvalidate_caches()
, то оно будет вызвано для выполнения аннулирования. Эта функция должна вызываться, если во время работы вашей программы создаются /устанавливаются какие-либо модули, чтобы гарантировать, что все поисковики заметят о существовании нового модуля.Добавлено в версии 3.3.
Изменено в версии 3.10: Замечаются пакеты пространства имен, созданные/установленные в другом расположении
sys.path
после того, как то же пространство имен уже было импортировано.
- importlib.reload(module)¶
Перезагрузите ранее импортированный module. Аргументом должен быть объект module, поэтому он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля с помощью внешнего редактора и хотите опробовать новую версию, не выходя из интерпретатора Python. Возвращаемое значение - это объект модуля (который может отличаться, если при повторном импорте другой объект будет помещен в
sys.modules
).Когда выполняется
reload()
:Код модуля Python перекомпилируется, и код на уровне модуля выполняется повторно, определяя новый набор объектов, которые привязаны к именам в словаре модуля, путем повторного использования loader, который первоначально загружал модуль. Функция
init
модулей расширения не вызывается во второй раз.Как и в случае со всеми другими объектами в Python, старые объекты восстанавливаются только после того, как количество их ссылок упадет до нуля.
Имена в пространстве имен модулей обновляются, чтобы указывать на любые новые или измененные объекты.
Другие ссылки на старые объекты (например, имена, внешние по отношению к модулю) не восстанавливаются для ссылки на новые объекты и должны обновляться в каждом пространстве имен, где они встречаются, если это необходимо.
Есть ряд других предостережений:
При перезагрузке модуля его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределение имен переопределяет старые определения, так что, как правило, это не проблема. Если новая версия модуля не определяет имя, которое было определено в старой версии, старое определение остается. Эта функция может быть использована в интересах модуля, если он поддерживает глобальную таблицу или кэш объектов - с помощью инструкции
try
он может проверить наличие таблицы и при желании пропустить ее инициализацию:try: cache except NameError: cache = {}
Как правило, не очень полезно перезагружать встроенные или динамически загружаемые модули. Перезагрузка
sys
,__main__
,builtins
и других ключевых модулей не рекомендуется. Во многих случаях модули расширения не предназначены для инициализации более одного раза и могут выходить из строя произвольным образом при перезагрузке.Если модуль импортирует объекты из другого модуля, используя
from
…import
…, вызовreload()
для другого модуля не приводит к переопределению импортированных из него объектов — один из способов обойти это - повторно выполнитьfrom
утверждение, другое - использовать вместо негоimport
и полные имена (module.name).Если модуль создает экземпляры класса, перезагрузка модуля, который определяет класс, не влияет на определения методов экземпляров - они продолжают использовать старое определение класса. То же самое верно и для производных классов.
Добавлено в версии 3.4.
Изменено в версии 3.7:
ModuleNotFoundError
вызывается, когда в перезагружаемом модуле отсутствуетModuleSpec
.
importlib.abc
– Абстрактные базовые классы, связанные с импортом¶
Исходный код: Lib/importlib/abc.py
Модуль importlib.abc
содержит все основные абстрактные базовые классы, используемые в import
. Также предоставляются некоторые подклассы основных абстрактных базовых классов, которые помогают в реализации основных азбук.
Иерархия ABC:
object
+-- Finder (deprecated)
+-- MetaPathFinder
+-- PathEntryFinder
+-- Loader
+-- ResourceLoader --------+
+-- InspectLoader |
+-- ExecutionLoader --+
+-- FileLoader
+-- SourceLoader
- class importlib.abc.Finder¶
Абстрактный базовый класс, представляющий собой finder.
Не рекомендуется, начиная с версии 3.3: Вместо этого используйте
MetaPathFinder
илиPathEntryFinder
.- abstractmethod find_module(fullname, path=None)¶
Абстрактный метод для поиска loader для указанного модуля. Первоначально указанный в PEP 302, этот метод предназначался для использования в
sys.meta_path
и в подсистеме импорта на основе путей.Изменено в версии 3.4: Возвращает
None
при вызове вместоNotImplementedError
.Не рекомендуется, начиная с версии 3.10: Вместо этого реализуйте
MetaPathFinder.find_spec()
илиPathEntryFinder.find_spec()
.
- class importlib.abc.MetaPathFinder¶
Абстрактный базовый класс, представляющий собой meta path finder.
Добавлено в версии 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder
.- find_spec(fullname, path, target=None)¶
Абстрактный метод для поиска spec для указанного модуля. Если это импорт верхнего уровня, path будет
None
. В противном случае это поиск подпакета или модуля, и path будет значением__path__
из родительского пакета. Если спецификация не может быть найдена, возвращаетсяNone
. При передачеtarget
это объект модуля, который finder может использовать для более обоснованного предположения о том, какую спецификацию возвращать.importlib.util.spec_from_loader()
может быть полезен для реализации конкретногоMetaPathFinders
.Добавлено в версии 3.4.
- find_module(fullname, path)¶
Устаревший метод поиска loader для указанного модуля. Если это импорт верхнего уровня, path будет
None
. В противном случае это поиск подпакета или модуля, и path будет значением__path__
из родительского пакета. Если загрузчик не может быть найден, возвращаетсяNone
.Если определено значение
find_spec()
, то обеспечивается обратная совместимость функциональных возможностей.Изменено в версии 3.4: Возвращает
None
при вызове вместоNotImplementedError
. Можно использоватьfind_spec()
для обеспечения функциональности.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
find_spec()
.
- invalidate_caches()¶
Необязательный метод, который при вызове должен аннулировать любой внутренний кэш, используемый программой поиска. Используется
importlib.invalidate_caches()
при аннулировании кэшей всех средств поиска наsys.meta_path
.Изменено в версии 3.4: Возвращает
None
при вызове вместоNotImplemented
.
- class importlib.abc.PathEntryFinder¶
Абстрактный базовый класс, представляющий path entry finder. Хотя он имеет некоторое сходство с
MetaPathFinder
,PathEntryFinder
, предназначен для использования только в рамках подсистемы импорта на основе путей, предоставляемойimportlib.machinery.PathFinder
.Добавлено в версии 3.3.
Изменено в версии 3.10: Больше не является подклассом
Finder
.- find_spec(fullname, target=None)¶
Абстрактный метод поиска spec для указанного модуля. Программа поиска будет выполнять поиск модуля только в пределах path entry, которому он назначен. Если спецификация не может быть найдена, возвращается
None
. При передачеtarget
является объектом модуля, который finder может использовать для более обоснованного предположения о том, какую спецификацию возвращать.importlib.util.spec_from_loader()
может быть полезно для реализации конкретногоPathEntryFinders
.Добавлено в версии 3.4.
- find_loader(fullname)¶
Устаревший метод поиска loader для указанного модуля. Возвращает 2-й кортеж из
(loader, portion)
, гдеportion
- это последовательность расположений файловой системы, составляющих часть пакета пространства имен. Загрузчиком может бытьNone
, при этом указываетсяportion
для обозначения вклада местоположений файловой системы в пакет пространства имен. Пустой список можно использовать для обозначенияportion
, чтобы указать, что загрузчик не является частью пакета пространства имен. Еслиloader
равноNone
, аportion
- это пустой список, то не найден загрузчик или местоположение пакета пространства имен (т.е. не удалось найти что-либо для модуля).Если определено значение
find_spec()
, то обеспечивается обратная совместимость функциональных возможностей.Изменено в версии 3.4: Возвращает
(None, [])
вместоNotImplementedError
. Используетfind_spec()
, когда это возможно, для обеспечения функциональности.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
find_spec()
.
- find_module(fullname)¶
Конкретная реализация
Finder.find_module()
, которая эквивалентнаself.find_loader(fullname)[0]
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
find_spec()
.
- invalidate_caches()¶
Необязательный метод, который при вызове должен аннулировать любой внутренний кэш, используемый программой поиска. Используется
importlib.machinery.PathFinder.invalidate_caches()
при аннулировании кэшей всех кэшированных средств поиска.
- class importlib.abc.Loader¶
Абстрактный базовый класс для loader. Точное определение загрузчика приведено в PEP 302.
Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать метод
get_resource_reader()
, указанный вimportlib.resources.abc.ResourceReader
.Изменено в версии 3.7: Введен необязательный метод
get_resource_reader()
.- create_module(spec)¶
Метод, который возвращает объект module для использования при импорте модуля. Этот метод может возвращать
None
, указывая, что должна выполняться семантика создания модуля по умолчанию.Добавлено в версии 3.4.
Изменено в версии 3.6: Этот метод больше не является необязательным, когда определен
exec_module()
.
- exec_module(module)¶
Абстрактный метод, который выполняет модуль в его собственном пространстве имен при импорте или перезагрузке модуля. Модуль уже должен быть инициализирован при вызове
exec_module()
. Если этот метод существует, необходимо определитьcreate_module()
.Добавлено в версии 3.4.
Изменено в версии 3.6:
create_module()
также должен быть определен.
- load_module(fullname)¶
Устаревший метод загрузки модуля. Если модуль не может быть загружен, выводится значение
ImportError
, в противном случае возвращается загруженный модуль.Если запрошенный модуль уже существует в
sys.modules
, этот модуль следует использовать и перезагрузить. В противном случае загрузчик должен создать новый модуль и вставить его вsys.modules
перед началом любой загрузки, чтобы предотвратить рекурсию при импорте. Если загрузчик вставил модуль и загрузка завершилась неудачно, он должен быть удален загрузчиком изsys.modules
; модули, которые уже были вsys.modules
до начала выполнения загрузчика, следует оставить в покое (см.importlib.util.module_for_loader()
).Загрузчик должен установить несколько атрибутов для модуля (обратите внимание, что некоторые из этих атрибутов могут измениться при перезагрузке модуля).:
__name__
Полное имя модуля. Это
'__main__'
для выполняемого модуля.
__cached__
Имя файла скомпилированной версии кода модуля. Оно задается не во всех модулях (например, встроенных модулях).
__path__
Список местоположений, в которых будут найдены подмодули пакета. В большинстве случаев это один каталог. Система импорта передает этот атрибут
__import__()
и средствам поиска таким же образом, как иsys.path
, но только для пакета. Он не задается для модулей, не входящих в пакет, поэтому его можно использовать как индикатор того, что модуль является пакетом.
__package__
Полное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же самое, что
__name__
.
__loader__
loader, используемый для загрузки модуля.
Если доступно значение
exec_module()
, то обеспечивается обратная совместимость функций.Изменено в версии 3.4: При вызове вызывается значение
ImportError
вместоNotImplementedError
. Функциональность, предоставляемая при наличииexec_module()
.Не рекомендуется, начиная с версии 3.4: Рекомендуемый API для загрузки модуля -
exec_module()
(иcreate_module()
). Загрузчики должны реализовать его вместоload_module()
. Механизм импорта берет на себя все остальные обязанностиload_module()
при внедренииexec_module()
.
- module_repr(module)¶
Устаревший метод, который при реализации вычисляет и возвращает представление данного модуля в виде строки. Тип модуля по умолчанию
__repr__()
будет использовать результат этого метода соответствующим образом.Добавлено в версии 3.3.
Изменено в версии 3.4: Сделан необязательным вместо абстрактного метода.
Не рекомендуется, начиная с версии 3.4: Импортное оборудование теперь заботится об этом автоматически.
- class importlib.abc.ResourceLoader¶
Абстрактный базовый класс для loader, который реализует необязательный протокол PEP 302 для загрузки произвольных ресурсов из серверной части хранилища.
Не рекомендуется, начиная с версии 3.7: Этот ABC устарел в пользу поддержки загрузки ресурсов через
importlib.resources.abc.ResourceReader
.- abstractmethod get_data(path)¶
Абстрактный метод, возвращающий байты для данных, расположенных по адресу path. Загрузчики, у которых есть серверная часть хранилища, похожая на файл, которая позволяет хранить произвольные данные, могут реализовать этот абстрактный метод, чтобы предоставить прямой доступ к сохраненным данным.
OSError
должен быть поднят, если путь не может быть найден. Ожидается, что path будет создан с использованием атрибута__file__
модуля или элемента из__path__
пакета.Изменено в версии 3.4: Выводит значение
OSError
вместоNotImplementedError
.
- class importlib.abc.InspectLoader¶
Абстрактный базовый класс для loader, который реализует необязательный протокол PEP 302 для загрузчиков, которые проверяют модули.
- get_code(fullname)¶
Возвращает объект code для модуля или
None
, если у модуля нет объекта code (как это было бы, например, для встроенного модуля). ВызовитеImportError
, если загрузчик не может найти запрошенный модуль.Примечание
Хотя этот метод имеет реализацию по умолчанию, рекомендуется по возможности переопределить его для повышения производительности.
Изменено в версии 3.4: Это уже не абстрактный подход, а конкретная реализация.
- abstractmethod get_source(fullname)¶
Абстрактный метод, возвращающий исходный код модуля. Он возвращается в виде текстовой строки с использованием universal newlines, переводя все распознанные разделители строк в символы
'\n'
. ВозвращаетNone
, если источник недоступен (например, встроенный модуль). ВозвращаетImportError
, если загрузчик не может найти указанный модуль.Изменено в версии 3.4: Выводит значение
ImportError
вместоNotImplementedError
.
- is_package(fullname)¶
Необязательный метод, возвращающий значение true, если модуль является пакетом, и значение false в противном случае.
ImportError
вызывается, если loader не удается найти модуль.Изменено в версии 3.4: Выводит значение
ImportError
вместоNotImplementedError
.
- static source_to_code(data, path='<string>')¶
Создайте объект кода из исходного кода Python.
Аргументом data может быть все, что поддерживает функция
compile()
(например, строка или байты). Аргументом path должен быть «путь» к источнику исходного кода, который может быть абстрактным понятием (например, расположение в zip-файле).С последующим объектом кода его можно выполнить в модуле, выполнив команду
exec(code, module.__dict__)
.Добавлено в версии 3.4.
Изменено в версии 3.5: Сделал метод статичным.
- exec_module(module)¶
Реализация
Loader.exec_module()
.Добавлено в версии 3.4.
- load_module(fullname)¶
Реализация
Loader.load_module()
.Не рекомендуется, начиная с версии 3.4: вместо этого используйте
exec_module()
.
- class importlib.abc.ExecutionLoader¶
Абстрактный базовый класс, наследуемый от
InspectLoader
, который при реализации помогает модулю выполняться как скрипт. ABC представляет собой необязательный протокол PEP 302.- abstractmethod get_filename(fullname)¶
Абстрактный метод, который должен возвращать значение
__file__
для указанного модуля. Если путь недоступен, вызывается значениеImportError
.Если доступен исходный код, то метод должен возвращать путь к исходному файлу, независимо от того, использовался ли байт-код для загрузки модуля.
Изменено в версии 3.4: Выводит значение
ImportError
вместоNotImplementedError
.
- class importlib.abc.FileLoader(fullname, path)¶
Абстрактный базовый класс, который наследуется от
ResourceLoader
иExecutionLoader
, предоставляя конкретные реализацииResourceLoader.get_data()
иExecutionLoader.get_filename()
.Аргумент fullname - это полностью разрешенное имя модуля, с которым должен работать загрузчик. Аргумент path - это путь к файлу модуля.
Добавлено в версии 3.3.
- name¶
Имя модуля, с которым может работать загрузчик.
- path¶
Путь к файлу модуля.
- load_module(fullname)¶
Вызывает команду super’s
load_module()
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
Loader.exec_module()
.
- abstractmethod get_data(path)¶
Считывает path как двоичный файл и возвращает байты из него.
- class importlib.abc.SourceLoader¶
Абстрактный базовый класс для реализации загрузки исходного кода (и, возможно, байт-кода) в файл. Класс наследуется как от
ResourceLoader
, так и отExecutionLoader
, что требует реализации: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)¶
Необязательный абстрактный метод, который записывает указанные байты в путь к файлу. Все промежуточные каталоги, которые не существуют, должны создаваться автоматически.
Когда запись в path завершается ошибкой, поскольку путь доступен только для чтения (
errno.EACCES
/PermissionError
), не распространяйте исключение.Изменено в версии 3.4: Больше не вызывает
NotImplementedError
при вызове.
- get_code(fullname)¶
Конкретная реализация
InspectLoader.get_code()
.
- exec_module(module)¶
Конкретная реализация
Loader.exec_module()
.Добавлено в версии 3.4.
- load_module(fullname)¶
Конкретная реализация
Loader.load_module()
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
exec_module()
.
- get_source(fullname)¶
Конкретная реализация
InspectLoader.get_source()
.
- is_package(fullname)¶
Конкретная реализация
InspectLoader.is_package()
. Модуль считается пакетом, если путь к его файлу (как указано вExecutionLoader.get_filename()
) является файлом с именем__init__
при удалении расширения файла ** и** само имя модуля не заканчивается на__init__
.
importlib.machinery
– Импортеры и перехватчики путей¶
Исходный код: Lib/importlib/machinery.py
Этот модуль содержит различные объекты, которые помогают import
находить и загружать модули.
- importlib.machinery.SOURCE_SUFFIXES¶
Список строк, представляющих распознанные файловые суффиксы для исходных модулей.
Добавлено в версии 3.3.
- importlib.machinery.DEBUG_BYTECODE_SUFFIXES¶
Список строк, представляющих файловые суффиксы для неоптимизированных модулей байт-кода.
Добавлено в версии 3.3.
Не рекомендуется, начиная с версии 3.5: Вместо этого используйте
BYTECODE_SUFFIXES
.
- importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES¶
Список строк, представляющих файловые суффиксы для оптимизированных модулей байт-кода.
Добавлено в версии 3.3.
Не рекомендуется, начиная с версии 3.5: Вместо этого используйте
BYTECODE_SUFFIXES
.
- importlib.machinery.BYTECODE_SUFFIXES¶
Список строк, представляющих распознанные файловые суффиксы для модулей байт-кода (включая начальную точку).
Добавлено в версии 3.3.
Изменено в версии 3.5: Это значение больше не зависит от
__debug__
.
- importlib.machinery.EXTENSION_SUFFIXES¶
Список строк, представляющих распознанные файловые суффиксы для модулей расширения.
Добавлено в версии 3.3.
- importlib.machinery.all_suffixes()¶
Возвращает сводный список строк, представляющих все файловые суффиксы для модулей, распознанных стандартным механизмом импорта. Это вспомогательный инструмент для кода, которому просто нужно знать, относится ли путь к файловой системе потенциально к модулю, без каких-либо подробностей о типе модуля (например,
inspect.getmodulename()
).Добавлено в версии 3.3.
- class importlib.machinery.BuiltinImporter¶
importer для встроенных модулей. Все известные встроенные модули перечислены в
sys.builtin_module_names
. Этот класс реализуетimportlib.abc.MetaPathFinder
иimportlib.abc.InspectLoader
Азбуки.В этом классе определены только методы класса, чтобы уменьшить необходимость в создании экземпляров.
Изменено в версии 3.5: Как часть PEP 489, встроенный импортер теперь реализует
Loader.create_module()
иLoader.exec_module()
- class importlib.machinery.FrozenImporter¶
importer для замороженных модулей. Этот класс реализует
importlib.abc.MetaPathFinder
иimportlib.abc.InspectLoader
Азбуки.В этом классе определены только методы класса, чтобы уменьшить необходимость в создании экземпляров.
Изменено в версии 3.4: Получены методы
create_module()
иexec_module()
.
- class importlib.machinery.WindowsRegistryFinder¶
Finder для модулей, объявленных в реестре Windows. Этот класс реализует
importlib.abc.MetaPathFinder
ABC.В этом классе определены только методы класса, чтобы уменьшить необходимость в создании экземпляров.
Добавлено в версии 3.3.
Не рекомендуется, начиная с версии 3.6: Вместо этого используйте конфигурацию
site
. В будущих версиях Python этот поисковик может быть отключен по умолчанию.
- class importlib.machinery.PathFinder¶
Finder для атрибутов
sys.path
и package__path__
. Этот класс реализуетimportlib.abc.MetaPathFinder
ABC.В этом классе определены только методы класса, чтобы уменьшить необходимость в создании экземпляров.
- classmethod find_spec(fullname, path=None, target=None)¶
Метод класса, который пытается найти spec для модуля, указанного с помощью fullname в
sys.path
или, если он определен, в path. Для каждой записи пути, в которой выполняется поиск, проверяетсяsys.path_importer_cache
. Если найден объект, не являющийся ложным, то он используется в качестве path entry finder для поиска искомого модуля. Если запись не найдена вsys.path_importer_cache
, то выполняется поиск вsys.path_hooks
для записи пути и, если она найдена, сохраняется вsys.path_importer_cache
вместе с запросом о модуле. Если программа поиска так и не будет найдена, тоNone
сохраняется в кэше и возвращается обратно.Добавлено в версии 3.4.
Изменено в версии 3.5: Если текущий рабочий каталог, представленный пустой строкой, больше не является допустимым, то возвращается
None
, но значение вsys.path_importer_cache
не кэшируется.
- classmethod find_module(fullname, path=None)¶
Устаревшая оболочка вокруг
find_spec()
.Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
find_spec()
.
- classmethod invalidate_caches()¶
Вызывает
importlib.abc.PathEntryFinder.invalidate_caches()
для всех средств поиска, сохраненных вsys.path_importer_cache
, которые определяют метод. В противном случае записи вsys.path_importer_cache
, имеющие значениеNone
, будут удалены.Изменено в версии 3.7: Записи
None
вsys.path_importer_cache
будут удалены.
Изменено в версии 3.4: Вызывает объекты в
sys.path_hooks
с текущим рабочим каталогом для''
(т.е. пустую строку).
- class importlib.machinery.FileFinder(path, *loader_details)¶
Конкретная реализация
importlib.abc.PathEntryFinder
, которая кэширует результаты из файловой системы.Аргумент path - это каталог, по которому программа finder отвечает за поиск.
Аргумент loader_details представляет собой переменное количество кортежей из 2 элементов, каждый из которых содержит загрузчик и последовательность файловых суффиксов, распознаваемых загрузчиком. Ожидается, что загрузчики будут вызываемыми, которые принимают два аргумента в виде имени модуля и пути к найденному файлу.
Finder будет кэшировать содержимое каталога по мере необходимости, выполняя статистические запросы для каждого модуля поиска, чтобы убедиться, что кэш не устарел. Поскольку устаревание кэша зависит от степени детализации информации операционной системы о состоянии файловой системы, существует потенциальная проблема поиска модуля, создания нового файла и последующего поиска модуля, который представляет новый файл. Если операции выполняются достаточно быстро, чтобы соответствовать уровню детализации вызовов stat, то поиск модуля завершится неудачей. Чтобы этого не произошло, при динамическом создании модуля обязательно вызывайте
importlib.invalidate_caches()
.Добавлено в версии 3.3.
- path¶
Путь, по которому finder будет выполнять поиск.
- find_spec(fullname, target=None)¶
Попытайтесь найти спецификацию для обработки полного имени в пределах
path
.Добавлено в версии 3.4.
- find_loader(fullname)¶
Попытайтесь найти загрузчик, который будет обрабатывать полное имя в пределах
path
.Не рекомендуется, начиная с версии 3.10: Вместо этого используйте
find_spec()
.
- invalidate_caches()¶
Очистите внутренний кэш.
- classmethod path_hook(*loader_details)¶
Метод класса, который возвращает замыкание для использования в
sys.path_hooks
. ЭкземплярFileFinder
возвращается замыканием, используя аргумент path, заданный непосредственно замыканию, и loader_details косвенно.Если аргументом для закрытия не является существующий каталог, то выводится значение
ImportError
.
- class importlib.machinery.SourceFileLoader(fullname, path)¶
Конкретная реализация
importlib.abc.SourceLoader
путем создания подклассаimportlib.abc.FileLoader
и предоставления некоторых конкретных реализаций других методов.Добавлено в версии 3.3.
- name¶
Имя модуля, с которым будет работать этот загрузчик.
- path¶
Путь к исходному файлу.
- path_stats(path)¶
Конкретная реализация
importlib.abc.SourceLoader.path_stats()
.
- set_data(path, data)¶
Конкретная реализация
importlib.abc.SourceLoader.set_data()
.
- load_module(name=None)¶
Конкретная реализация
importlib.abc.Loader.load_module()
, где указание имени загружаемого модуля необязательно.Не рекомендуется, начиная с версии 3.6: Вместо этого используйте
importlib.abc.Loader.exec_module()
.
- class importlib.machinery.SourcelessFileLoader(fullname, path)¶
Конкретная реализация
importlib.abc.FileLoader
, которая может импортировать файлы байт-кода (т.е. файлов с исходным кодом не существует).Пожалуйста, обратите внимание, что прямое использование файлов байт-кода (и, следовательно, не файлов исходного кода) препятствует использованию ваших модулей всеми реализациями Python или новыми версиями Python, которые изменяют формат байт-кода.
Добавлено в версии 3.3.
- name¶
Имя модуля, с которым будет работать загрузчик.
- path¶
Путь к файлу с байт-кодом.
- get_source(fullname)¶
Возвращает
None
, поскольку файлы байт-кода не имеют источника при использовании этого загрузчика.
- load_module(name=None)¶
Конкретная реализация
importlib.abc.Loader.load_module()
, где указание имени загружаемого модуля необязательно.Не рекомендуется, начиная с версии 3.6: Вместо этого используйте
importlib.abc.Loader.exec_module()
.
- class importlib.machinery.ExtensionFileLoader(fullname, path)¶
Конкретная реализация
importlib.abc.ExecutionLoader
для модулей расширения.Аргумент fullname указывает имя модуля, который должен поддерживаться загрузчиком. Аргумент path - это путь к файлу модуля расширения.
Добавлено в версии 3.3.
- name¶
Название модуля, поддерживаемого загрузчиком.
- path¶
Путь к модулю расширения.
- create_module(spec)¶
Создает объект модуля из заданной спецификации в соответствии с PEP 489.
Добавлено в версии 3.5.
- exec_module(module)¶
Инициализирует данный объект модуля в соответствии с PEP 489.
Добавлено в версии 3.5.
- is_package(fullname)¶
Возвращает
True
, если путь к файлу указывает на модуль пакета__init__
, основанный наEXTENSION_SUFFIXES
.
- get_code(fullname)¶
Возвращает
None
, поскольку в модулях расширения отсутствует объект кода.
- get_source(fullname)¶
Возвращает
None
, поскольку модули расширения не содержат исходного кода.
- class importlib.machinery.NamespaceLoader(name, path, path_finder)¶
Конкретная реализация
importlib.abc.InspectLoader
для пакетов пространства имен. Это псевдоним для закрытого класса, который становится общедоступным только для самоанализа атрибута__loader__
для пакетов пространства имен:>>> from importlib.machinery import NamespaceLoader >>> import my_namespace >>> isinstance(my_namespace.__loader__, NamespaceLoader) True >>> import importlib.abc >>> isinstance(my_namespace.__loader__, importlib.abc.Loader) True
Добавлено в версии 3.11.
- class importlib.machinery.ModuleSpec(name, loader, *, origin=None, loader_state=None, is_package=None)¶
Спецификация состояния модуля, связанного с импортом системы. Обычно это значение указывается как атрибут модуля
__spec__
. В приведенных ниже описаниях имена в круглых скобках указывают на соответствующий атрибут, доступный непосредственно в объекте module, например,module.__spec__.origin == module.__file__
. Однако обратите внимание, что, хотя значения * обычно эквивалентны, они могут отличаться, поскольку между двумя объектами нет синхронизации. Например, можно обновить__file__
модуля во время выполнения, и это не будет автоматически отражено в__spec__.origin
модуля, и наоборот.Добавлено в версии 3.4.
- name¶
(
__name__
)Полное имя модуля. Для finder всегда следует присваивать этому атрибуту значение непустой строки.
- loader¶
Параметр loader, используемый для загрузки модуля. Параметр finder всегда должен устанавливать этот атрибут.
- origin¶
(
__file__
)Расположение, которое loader следует использовать для загрузки модуля. Например, для модулей, загружаемых из файла .py, это имя файла. Для finder всегда следует присваивать этому атрибуту значимое значение, чтобы использовать loader. В необычном случае, когда его нет (например, для пакетов пространства имен), для него должно быть установлено значение
None
.- submodule_search_locations¶
(
__path__
)Список местоположений, в которых будут найдены подмодули пакета. В большинстве случаев это один каталог. Для finder следует присвоить этому атрибуту значение списка, даже пустого, чтобы указать системе импорта, что модуль является пакетом. Для модулей, не входящих в пакет, должно быть установлено значение
None
. Позже оно автоматически устанавливается в специальный объект для пакетов пространства имен.- loader_state¶
Параметр finder может присваивать этот атрибут объекту, содержащему дополнительные данные, относящиеся к конкретному модулю, которые будут использоваться при загрузке модуля. В противном случае для него должно быть установлено значение
None
.- cached¶
Имя файла скомпилированной версии кода модуля. Этот атрибут всегда должен быть finder, но он может быть
None
для модулей, которым не требуется сохранять скомпилированный код.- parent¶
(Доступно только для чтения) Полное имя пакета, в котором находится модуль (или пустая строка для модуля верхнего уровня). Если модуль является пакетом, то это то же самое, что
name
.- has_location¶
importlib.util
– Служебный код для импортеров¶
Исходный код: Lib/importlib/util.py
Этот модуль содержит различные объекты, которые помогают в построении importer.
- importlib.util.MAGIC_NUMBER¶
Байты, которые представляют номер версии байт-кода. Если вам нужна помощь с загрузкой/записью байт-кода, то обратите внимание на
importlib.abc.SourceLoader
.Добавлено в версии 3.4.
- importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)¶
Возвращает PEP 3147/PEP 488 путь к скомпилированному в байтах файлу, связанному с исходным кодом path. Например, если path равен
/foo/bar/baz.py
, возвращаемое значение будет/foo/bar/__pycache__/baz.cpython-32.pyc
для Python 3.2. Строкаcpython-32
берется из текущего магического тега (см.get_tag()
; еслиsys.implementation.cache_tag
не определено, тогда будет поднятNotImplementedError
).Параметр optimization используется для указания уровня оптимизации файла байт-кода. Пустая строка не представляет никакой оптимизации, поэтому
/foo/bar/baz.py
с оптимизацией, равной''
, приведет к пути байт-кода, равному/foo/bar/__pycache__/baz.cpython-32.pyc
.None
что приводит к использованию уровня оптимизации интерпретатора. Используется строковое представление любого другого значения, поэтому/foo/bar/baz.py
с оптимизацией2
приведет к пути байт-кода/foo/bar/__pycache__/baz.cpython-32.opt-2.pyc
. Строковое представление optimization может быть только буквенно-цифровым, иначе возникаетValueError
.Параметр debug_override устарел и может использоваться для переопределения системного значения
__debug__
. ЗначениеTrue
эквивалентно установке значения optimization в пустую строку. ЗначениеFalse
равно значению параметра optimization, равному1
. Если оба параметра debug_override и optimization не являютсяNone
, то значениеTypeError
увеличивается.Добавлено в версии 3.4.
Изменено в версии 3.5: Был добавлен параметр optimization, а параметр debug_override был признан устаревшим.
Изменено в версии 3.6: Принимает значение path-like object.
- importlib.util.source_from_cache(path)¶
Учитывая путь к имени файла PEP 3147, верните соответствующий путь к файлу с исходным кодом. Например, если путь равен
/foo/bar/__pycache__/baz.cpython-32.pyc
, возвращаемый путь будет/foo/bar/baz.py
. path необязательно должен существовать, однако, если он не соответствует формату PEP 3147 или PEP 488, генерируетсяValueError
. Еслиsys.implementation.cache_tag
не определено, то вызываетсяNotImplementedError
.Добавлено в версии 3.4.
Изменено в версии 3.6: Принимает значение path-like object.
- importlib.util.decode_source(source_bytes)¶
Расшифруйте заданные байты, представляющие исходный код, и верните их в виде строки с универсальными символами новой строки (как того требует
importlib.abc.InspectLoader.get_source()
).Добавлено в версии 3.4.
- importlib.util.resolve_name(name, package)¶
Преобразуйте относительное имя модуля в абсолютное.
Если в name нет начальных точек, то просто возвращается name. Это позволяет использовать, например,
importlib.util.resolve_name('sys', __spec__.parent)
, не проверяя, нужен ли аргумент package.ImportError
вызывается, если name является относительным именем модуля, а package - ложным значением (например,None
или пустой строкой).ImportError
также вызывается, если относительное имя не используется в содержащем его пакете (например, при запросе..bacon
из пакетаspam
).Добавлено в версии 3.3.
Изменено в версии 3.9: Чтобы улучшить согласованность с инструкциями по импорту, увеличьте значение
ImportError
вместоValueError
для недопустимых попыток относительного импорта.
- importlib.util.find_spec(name, package=None)¶
Найдите spec для модуля, необязательно относительно указанного имени пакета. Если модуль находится в
sys.modules
, то возвращаетсяsys.modules[name].__spec__
(если только спецификация не будетNone
или не задана, и в этом случае вызываетсяValueError
). В противном случае выполняется поиск с использованиемsys.meta_path
.None
возвращается, если спецификация не найдена.Если имя относится к подмодулю (содержит точку), родительский модуль импортируется автоматически.
name и package работают так же, как и для
import_module()
.Добавлено в версии 3.4.
Изменено в версии 3.7: Вызывает
ModuleNotFoundError
вместоAttributeError
, если пакет на самом деле не является пакетом (т.е. не имеет атрибута__path__
).
- importlib.util.module_from_spec(spec)¶
Создайте новый модуль на основе спецификации и
spec.loader.create_module
.Если
spec.loader.create_module
не возвращаетNone
, то никакие ранее существовавшие атрибуты не будут сброшены. Кроме того, значениеAttributeError
не будет задано, если оно срабатывает при обращении к спецификации или установке атрибута в модуле.Эта функция предпочтительнее, чем использование
types.ModuleType
для создания нового модуля, поскольку spec используется для установки как можно большего количества контролируемых импортом атрибутов в модуле.Добавлено в версии 3.5.
- @importlib.util.module_for_loader¶
decorator для
importlib.abc.Loader.load_module()
, чтобы обработать выбор подходящего объекта модуля для загрузки. Ожидается, что оформленный метод будет иметь сигнатуру вызова, принимающую два позиционных аргумента (например,load_module(self, module)
), для которых вторым аргументом будет модуль object, который будет использоваться загрузчиком. Обратите внимание, что декоратор не будет работать со статическими методами из-за предположения о двух аргументах.Оформленный метод будет использовать имя загружаемого модуля, как и ожидалось для loader. Если модуль не найден в
sys.modules
, то создается новый модуль. Независимо от того, откуда был взят модуль,__loader__
устанавливается в self, а__package__
устанавливается на основе того, что возвращаетimportlib.abc.InspectLoader.is_package()
(если доступно). Эти атрибуты устанавливаются безоговорочно для поддержки перезагрузки.Если методом decorated вызвано исключение и модуль был добавлен в
sys.modules
, то модуль будет удален, чтобы предотвратить появление частично инициализированного модуля, оставшегося вsys.modules
. Если модуль уже был вsys.modules
, то он остается в покое.Изменено в версии 3.3:
__loader__
и__package__
устанавливаются автоматически (когда это возможно).Изменено в версии 3.4: Установите
__name__
,__loader__
__package__
безоговорочно для поддержки перезагрузки.Не рекомендуется, начиная с версии 3.4: Механизм импорта теперь напрямую выполняет все функции, предоставляемые этой функцией.
- @importlib.util.set_loader¶
decorator для
importlib.abc.Loader.load_module()
, чтобы установить атрибут__loader__
в возвращаемом модуле. Если атрибут уже установлен, декоратор ничего не делает. Предполагается, что первым позиционным аргументом обернутого метода (т.е.self
) является значение__loader__
.Изменено в версии 3.4: Установите
__loader__
, если задано значениеNone
, как если бы атрибут не существовал.Не рекомендуется, начиная с версии 3.4: Импортное оборудование позаботится об этом автоматически.
- @importlib.util.set_package¶
decorator для
importlib.abc.Loader.load_module()
, чтобы установить атрибут__package__
в возвращаемом модуле. Если задано значение__package__
и оно имеет значение, отличное отNone
, оно не будет изменено.Не рекомендуется, начиная с версии 3.4: Импортное оборудование позаботится об этом автоматически.
- importlib.util.spec_from_loader(name, loader, *, origin=None, is_package=None)¶
Фабричная функция для создания экземпляра
ModuleSpec
на основе загрузчика. Параметры имеют то же значение, что и для ModuleSpec. Функция использует доступный loader API, такие какInspectLoader.is_package()
, для заполнения любой недостающей информации в спецификации.Добавлено в версии 3.4.
- importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)¶
Заводская функция для создания экземпляра
ModuleSpec
на основе пути к файлу. Недостающая информация будет восполнена в спецификации с использованием API-интерфейсов загрузки и подразумевается, что модуль будет основан на файлах.Добавлено в версии 3.4.
Изменено в версии 3.6: Принимает значение path-like object.
- importlib.util.source_hash(source_bytes)¶
Возвращает хэш source_bytes в виде байт. Файл, основанный на хэше
.pyc
, вставляетsource_hash()
содержимого соответствующего исходного файла в свой заголовок.Добавлено в версии 3.7.
- class importlib.util.LazyLoader(loader)¶
Класс, который откладывает выполнение загрузчика модуля до тех пор, пока модуль не получит доступ к атрибуту.
Этот класс ** работает только с загрузчиками, которые определяют
exec_module()
, поскольку требуется контроль над тем, какой тип модуля используется для данного модуля. По тем же причинам метод загрузчикаcreate_module()
должен возвращатьNone
или тип, для которого его атрибут__class__
может быть изменен, а также не использовать slots. Наконец, модули, которые заменяют объект, помещенный вsys.modules
, не будут работать, поскольку нет способа правильно и безопасно заменить ссылки на модули во всем интерпретаторе;ValueError
вызывается при обнаружении такой замены.Примечание
Для проектов, где время запуска имеет решающее значение, этот класс позволяет потенциально минимизировать затраты на загрузку модуля, если он никогда не используется. Для проектов, где время запуска не имеет существенного значения, использование этого класса ** сильно ** не рекомендуется из-за того, что сообщения об ошибках, создаваемые во время загрузки, откладываются и, таким образом, возникают вне контекста.
Добавлено в версии 3.5.
Изменено в версии 3.6: Начал вызывать
create_module()
, удаляя предупреждение о совместимости дляimportlib.machinery.BuiltinImporter
иimportlib.machinery.ExtensionFileLoader
.- classmethod factory(loader)¶
Метод класса, который возвращает вызываемый объект, создающий отложенный загрузчик. Он предназначен для использования в ситуациях, когда загрузчик передается классом, а не экземпляром.
suffixes = importlib.machinery.SOURCE_SUFFIXES loader = importlib.machinery.SourceFileLoader lazy_loader = importlib.util.LazyLoader.factory(loader) finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))
Примеры¶
Программный импорт¶
Чтобы программно импортировать модуль, используйте importlib.import_module()
.
import importlib
itertools = importlib.import_module('itertools')
Проверка возможности импорта модуля¶
Если вам нужно выяснить, можно ли импортировать модуль без фактического выполнения импорта, то вам следует использовать importlib.util.find_spec()
.
Обратите внимание, что если name
является подмодулем (содержит точку), то importlib.util.find_spec()
импортирует родительский модуль.
import importlib.util
import sys
# For illustrative purposes.
name = 'itertools'
if name in sys.modules:
print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
# If you chose to perform the actual import ...
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
spec.loader.exec_module(module)
print(f"{name!r} has been imported")
else:
print(f"can't find the {name!r} module")
Прямой импорт исходного файла¶
Чтобы напрямую импортировать исходный файл Python, воспользуйтесь следующим рецептом:
import importlib.util
import sys
# For illustrative purposes.
import tokenize
file_path = tokenize.__file__
module_name = tokenize.__name__
spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
Реализация отложенного импорта¶
В приведенном ниже примере показано, как реализовать отложенный импорт:
>>> import importlib.util
>>> import sys
>>> def lazy_import(name):
... spec = importlib.util.find_spec(name)
... loader = importlib.util.LazyLoader(spec.loader)
... spec.loader = loader
... module = importlib.util.module_from_spec(spec)
... sys.modules[name] = module
... loader.exec_module(module)
... return module
...
>>> lazy_typing = lazy_import("typing")
>>> #lazy_typing is a real module object,
>>> #but it is not loaded in memory yet.
>>> lazy_typing.TYPE_CHECKING
False
Создание импортера¶
Для глубокой настройки импорта обычно требуется реализовать importer. Это означает управление как finder, так и loader аспектами. Для гурманов есть два вкуса на выбор в зависимости от ваших потребностей: meta path finder или path entry finder. Первое - это то, что вы бы добавили в sys.meta_path
, в то время как второе - это то, что вы создаете, используя path entry hook в sys.path_hooks
, которое работает с sys.path
записями, чтобы потенциально создать finder. В этом примере показано, как зарегистрировать ваши собственные импортеры, чтобы их можно было использовать в import (чтобы создать импортер для себя, ознакомьтесь с документацией по соответствующим классам, определенным в этом пакете).:
import importlib.machinery
import sys
# For illustrative purposes only.
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
importlib.machinery.SOURCE_SUFFIXES)
# Setting up a meta path finder.
# Make sure to put the finder in the proper location in the list in terms of
# priority.
sys.meta_path.append(SpamMetaPathFinder)
# Setting up a path entry finder.
# Make sure to put the path hook in the proper location in the list in terms
# of priority.
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))
Приближенное значение importlib.import_module()
¶
Сам импорт реализован в коде Python, что позволяет использовать большинство механизмов импорта через importlib. Ниже приведены примеры различных API, которые предоставляет importlib, на примере примерной реализации importlib.import_module()
:
import importlib.util
import sys
def import_module(name, package=None):
"""An approximate implementation of import."""
absolute_name = importlib.util.resolve_name(name, package)
try:
return sys.modules[absolute_name]
except KeyError:
pass
path = None
if '.' in absolute_name:
parent_name, _, child_name = absolute_name.rpartition('.')
parent_module = import_module(parent_name)
path = parent_module.__spec__.submodule_search_locations
for finder in sys.meta_path:
spec = finder.find_spec(absolute_name, path)
if spec is not None:
break
else:
msg = f'No module named {absolute_name!r}'
raise ModuleNotFoundError(msg, name=absolute_name)
module = importlib.util.module_from_spec(spec)
sys.modules[absolute_name] = module
spec.loader.exec_module(module)
if path is not None:
setattr(parent_module, child_name, module)
return module