Spec-Zone.ru › Python 3.13

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

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

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

Введение

Цель пакета importlib состоит из трёх пунктов.

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

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

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

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

См. также

Оператор import

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

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

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

The __import__() function

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

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

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

PEP 235

Импорт на платформах с регистронезависимым написанием

PEP 263

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

PEP 302

Новые плагины для импорта

PEP 328

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

PEP 366

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

PEP 420

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

PEP 451

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

PEP 488

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

PEP 489

Инициализация модулей расширения в несколько этапов

PEP 552

Детерминированные 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.invalidate_caches()

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

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

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

importlib.reload(module)

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

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

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

Есть ряд других предостережений:

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

try:
    cache
except NameError:
    cache = {}

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

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

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

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

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

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

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

Модуль importlib.abc содержит все основные абстрактные базовые классы, используемые import. Некоторые подклассы основных абстрактных базовых классов также предоставлены для помощи в реализации основных АБК.

Иерархия АБК:

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

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

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

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

find_spec(fullname, path, target=None)

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

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

invalidate_caches()

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

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

class importlib.abc.PathEntryFinder

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

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

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

find_spec(fullname, target=None)

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

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

invalidate_caches()

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

END_OF_DOCUMENT_MARKER
class importlib.abc.Loader

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

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

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

create_module(spec)

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

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

Изменено в версии 3.6: Этот метод больше не является необязательным, когда определён exec_module().

exec_module(module)

Абстрактный метод, выполняющий модуль в собственном пространстве имён при импорте или перезагрузке модуля. Модуль должен быть уже инициализирован, когда вызывается exec_module(). Когда этот метод существует, должен быть определён create_module().

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

Изменено в версии 3.6: Также должен быть определён create_module().

load_module(fullname)

Легасинский метод для загрузки модуля. Если модуль не может быть загружен, поднимается ImportError, в противном случае возвращается загруженный модуль.

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

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

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

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

Изменено в версии 3.4: Поднимает ImportError вместо NotImplementedError. Функциональность, предоставляемая, когда доступен exec_module().

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

class importlib.abc.ResourceLoader

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

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

abstractmethod get_data(path)

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

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

END_OF_DOCUMENT_MARKER
class importlib.abc.InspectLoader

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

get_code(fullname)

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

Примечание

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

Изменено в версии 3.4: Больше не абстрактный и предоставляется конкретная реализация.

abstractmethod get_source(fullname)

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

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

is_package(fullname)

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

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

static source_to_code(data, path='<string>')

Создает объект кода из исходного кода Python.

Аргумент data может быть любым, который поддерживает функция compile() (т.е. строка или байты). Аргумент path должен быть «путем» к исходному коду, что может быть абстрактным понятием (например, расположение в файле zip).

С помощью последующего объекта кода его можно выполнить в модуле, выполнив exec(code, module.__dict__).

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

Изменено в версии 3.5: Метод стал статическим.

exec_module(module)

Реализация Loader.exec_module().

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

load_module(fullname)

Реализация Loader.load_module().

Устарело начиная с версии 3.4: Используйте exec_module() вместо этого.

class importlib.abc.ExecutionLoader

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

abstractmethod get_filename(fullname)

Абстрактный метод, который должен вернуть значение __file__ для указанного модуля. Если путь недоступен, вызывается исключение ImportError.

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

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

class importlib.abc.FileLoader(fullname, path)

Абстрактный базовый класс, который наследуется от ResourceLoader и ExecutionLoader, предоставляющий конкретные реализации ResourceLoader.get_data() и ExecutionLoader.get_filename().

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

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

name

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

path

Путь к файлу модуля.

load_module(fullname)

Вызывает метод super’s load_module().

Устарело начиная с версии 3.4: Используйте Loader.exec_module() вместо этого.

abstractmethod get_filename(fullname)

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

abstractmethod get_data(path)

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

END_OF_DOCUMENT_MARKER
class importlib.abc.SourceLoader

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

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

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

Абстрактные методы, определённые этим классом, предназначены для добавления необязательной поддержки файлов байткода. Не реализация этих необязательных методов (или вызов исключения NotImplementedError) приводит к тому, что загрузчик будет работать только с исходным кодом. Реализация методов позволяет загрузчику работать с исходными и файлами байткода; она не позволяет выполнять загрузку без исходного кода, где предоставляется только байт код. Файлы байткода являются оптимизацией для ускорения загрузки путём удаления шага разбора компилятора Python, поэтому специфичный API для байткода не предоставляется.

path_stats(path)

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

  • 'mtime' (обязательно): целое или дробное число, представляющее время изменения исходного кода;
  • 'size' (необязательно): размер исходного кода в байтах.

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

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

Изменён в версии 3.4: Вызывается исключение OSError вместо NotImplementedError.

path_mtime(path)

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

Устарел начиная с версии 3.3: Этот метод устарел в пользу path_stats(). Вам не нужно его реализовывать, но он все ещё доступен для совместимости. Вызывается исключение OSError, если путь не может быть обработан.

Изменён в версии 3.4: Вызывается исключение OSError вместо NotImplementedError.

set_data(path, data)

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

При записи в путь, которая терпит неудачу из-за того, что путь является только для чтения (errno.EACCES/PermissionError), исключение не распространяется.

Изменён в версии 3.4: Больше не вызывает NotImplementedError при вызове.

get_code(fullname)

Конкретная реализация InspectLoader.get_code().

exec_module(module)

Конкретная реализация Loader.exec_module().

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

load_module(fullname)

Конкретная реализация Loader.load_module().

Устарел начиная с версии 3.4: Используйте exec_module() вместо этого.

get_source(fullname)

Конкретная реализация InspectLoader.get_source().

is_package(fullname)

Конкретная реализация InspectLoader.is_package(). Модуль определяется как пакет, если его путь к файлу (как предоставлено ExecutionLoader.get_filename()) является файлом с именем __init__ после удаления расширения файла и само имя модуля не заканчивается на __init__.

END_OF_DOCUMENT_MARKER
class importlib.abc.ResourceReader

Заменено на TraversableResources

Абстрактный базовый класс для чтения ресурсов.

С точки зрения этого АБК, ресурс — это бинарный артефакт, поставляемый вместе с пакетом. Обычно это, например, какой-нибудь файл данных, расположенный рядом с файлом __init__.py пакета. Цель этого класса — абстрагировать доступ к таким файлам данных, чтобы не иметь значения, хранятся ли пакет и его файлы данных, например, в файле zip или на файловой системе.

В любом из методов этого класса в качестве аргумента resource ожидается объект-путь, который концептуально представляет только имя файла. Это означает, что пути к подкаталогам в аргументе resource включать не следует. Это связано с тем, что расположение пакета, для которого предназначен чтец, выступает в качестве «каталога». Поэтому метафора каталогов и имён файлов — соответственно, пакеты и ресурсы. Именно поэтому экземпляры этого класса должны напрямую соответствовать конкретному пакету (а не потенциально представлять несколько пакетов или модуль).

Загрузчики, которые хотят поддерживать чтение ресурсов, должны предоставлять метод с именем get_resource_reader(fullname), который возвращает объект, реализующий интерфейс этого АБК. Если модуль, заданный параметром fullname, не является пакетом, этот метод должен возвращать None. Объект, совместимый с этим АБК, должен возвращаться только тогда, когда указанный модуль является пакетом.

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

Устарело начиная с версии 3.12, будет удалено в версии 3.14: Используйте importlib.resources.abc.TraversableResources вместо этого.

abstractmethod open_resource(resource)

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

Если ресурс не найден, генерируется исключение FileNotFoundError.

abstractmethod resource_path(resource)

Возвращает путь к ресурсу в файловой системе.

Если ресурс конкретно не существует в файловой системе, генерируется исключение FileNotFoundError.

abstractmethod is_resource(name)

Возвращает True, если указанное имя name считается ресурсом. Если name не существует, генерируется исключение FileNotFoundError.

abstractmethod contents()

Возвращает итерируемый объект строк, содержащий содержимое пакета. Обратите внимание, что не требуется, чтобы все имена, возвращаемые итератором, были фактическими ресурсами, например, допустимо возвращать имена, для которых is_resource() будет ложным.

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

Абстрактный метод возвращает итерируемый объект без элементов.

class importlib.abc.Traversable

Объект с подмножеством методов pathlib.Path, подходящих для обхода каталогов и открытия файлов.

Для представления объекта в файловой системе используйте importlib.resources.as_file().

Добавлен в версии 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)

Возвращает дочерний Traversable в self.

abstractmethod __truediv__(child)

Возвращает дочерний объект в Traversable.

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.

Загрузчики, которые хотят поддерживать чтение ресурсов, должны реализовать этот интерфейс.

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

Устарело начиная с версии 3.12, будет удалено в версии 3.14: Используйте importlib.resources.abc.TraversableResources вместо этого.

abstractmethod files()

Возвращает объект importlib.resources.abc.Traversable для загруженного пакета.

END_OF_DOCUMENT_MARKER

importlib.machinery – Импортёры и обработчики путей

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

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

importlib.machinery.SOURCE_SUFFIXES

Список строк, представляющих распознаваемые расширения файлов для исходных модулей.

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

importlib.machinery.DEBUG_BYTECODE_SUFFIXES

Список строк, представляющих расширения файлов для модулей неотредактированного байткода.

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

Устарел начиная с версии 3.5: Используйте BYTECODE_SUFFIXES вместо этого.

importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES

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

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

Устарел начиная с версии 3.5: Используйте BYTECODE_SUFFIXES вместо этого.

importlib.machinery.BYTECODE_SUFFIXES

Список строк, представляющих распознаваемые расширения файлов для модулей байткода (включая ведущую точку).

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

Изменено в версии 3.5: Значение больше не зависит от __debug__.

importlib.machinery.EXTENSION_SUFFIXES

Список строк, представляющих распознаваемые расширения файлов для модулей расширений.

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

importlib.machinery.all_suffixes()

Возвращает объединенный список строк, представляющих все расширения файлов для модулей, распознаваемых стандартной системой импорта. Это вспомогательная функция для кода, который просто нужно знать, может ли путь к файлу в файловой системе потенциально относиться к модулю, без необходимости в деталях о типе модуля (например, inspect.getmodulename()).

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

class importlib.machinery.BuiltinImporter

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

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

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

class importlib.machinery.FrozenImporter

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

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

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

class importlib.machinery.WindowsRegistryFinder

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

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

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

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

class importlib.machinery.PathFinder

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

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

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

Метод класса, который пытается найти спецификацию модуля, указанного параметром fullname в sys.path или, если определено, в path. Для каждой проверяемой записи пути проверяется sys.path_importer_cache. Если найдено не-ложное значение, оно используется в качестве поисковика записи пути для поиска искомого модуля. Если запись не найдена в sys.path_importer_cache, ищется sys.path_hooks для поиска поисковика для записи пути и, если найден, сохраняется в sys.path_importer_cache, а затем запрашивается о модуле. Если ни один поисковик не найден, None сохраняется в кэше и возвращается.

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

Изменено в версии 3.5: Если текущая рабочая директория (представленная пустой строкой) больше не действительна, то возвращается None, но значение не кэшируется в sys.path_importer_cache.

classmethod invalidate_caches()

Вызывает importlib.abc.PathEntryFinder.invalidate_caches() для всех поисковиков, сохраненных в sys.path_importer_cache, которые определяют этот метод. В противном случае записи в sys.path_importer_cache, установленные в None, удаляются.

Изменено в версии 3.7: Записи None в sys.path_importer_cache удаляются.

Изменено в версии 3.4: Вызывает объекты в sys.path_hooks с текущей рабочей директорией для '' (т. е. пустой строкой).

END_OF_DOCUMENT_MARKER
class importlib.machinery.FileFinder(path, *loader_details)

Конкретная реализация importlib.abc.PathEntryFinder, кэширующая результаты из файловой системы.

Аргумент path — это директория, за поиск в которой отвечает данный поиск.

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

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

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

path

Путь, по которому будет производиться поиск.

find_spec(fullname, target=None)

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

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

invalidate_caches()

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

classmethod path_hook(*loader_details)

Метод класса, возвращающий замыкание для использования с sys.path_hooks. Экземпляр FileFinder возвращается замыканием, используя аргумент path, переданный замыканию напрямую, и loader_details косвенно.

Если аргумент замыкания не является существующей директорией, возникает ImportError.

class importlib.machinery.SourceFileLoader(fullname, path)

Конкретная реализация importlib.abc.SourceLoader путём наследования от importlib.abc.FileLoader и предоставления некоторых конкретных реализаций других методов.

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

name

Имя модуля, который будет обрабатываться этим загрузчиком.

path

Путь к исходному файлу.

is_package(fullname)

Возвращает True, если path кажется предназначенным для пакета.

path_stats(path)

Конкретная реализация importlib.abc.SourceLoader.path_stats().

set_data(path, data)

Конкретная реализация importlib.abc.SourceLoader.set_data().

load_module(name=None)

Конкретная реализация importlib.abc.Loader.load_module(), где указание имени загружаемого модуля необязательно.

Устарело начиная с версии 3.6: Используйте importlib.abc.Loader.exec_module() вместо этого.

class importlib.machinery.SourcelessFileLoader(fullname, path)

Конкретная реализация importlib.abc.FileLoader, которая может импортировать файлы байткода (т.е. файлы исходного кода отсутствуют).

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

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

name

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

path

Путь к файлу байткода.

is_package(fullname)

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

get_code(fullname)

Возвращает объект кода для name, созданный из path.

get_source(fullname)

Возвращает None, поскольку в файлах байткода нет исходного кода при использовании этого загрузчика.

load_module(name=None)

Конкретная реализация importlib.abc.Loader.load_module(), где указание имени загружаемого модуля необязательно.

Устарело начиная с версии 3.6: Используйте importlib.abc.Loader.exec_module() вместо этого.

class importlib.machinery.ExtensionFileLoader(fullname, path)

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

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

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

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

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

name

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

path

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

create_module(spec)

Создаёт объект модуля по заданному описанию в соответствии с PEP 489.

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

exec_module(module)

Инициализирует заданный объект модуля в соответствии с PEP 489.

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

is_package(fullname)

Возвращает True, если путь к файлу указывает на модуль пакета, основанный на EXTENSION_SUFFIXES.

get_code(fullname)

Возвращает None, так как модули расширения не имеют объекта кода.

get_source(fullname)

Возвращает None, так как модули расширения не содержат исходный код.

get_filename(fullname)

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

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

class importlib.machinery.NamespaceLoader(name, path, path_finder)

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

>>> from importlib.machinery import NamespaceLoader
>>> import my_namespace
>>> isinstance(my_namespace.__loader__, NamespaceLoader)
True
>>> import importlib.abc
>>> isinstance(my_namespace.__loader__, importlib.abc.Loader)
True

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

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

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

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

name

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

loader

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

origin

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

submodule_search_locations

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

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

loader_state

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

cached

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

parent

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

has_location

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

END_OF_DOCUMENT_MARKER
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 . Это позволяет коду использовать путь к модулю в качестве точки отсчёта для навигации по файловой системе. Однако, происхождение спецификации будет ссылаться на расположение фактической двоичной библиотеки в папке .framework.

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

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

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

name

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

path

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

importlib.util – Утилитарный код для импортеров

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

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

importlib.util.MAGIC_NUMBER

Байты, представляющие номер версии байткода. Если вам нужна помощь с загрузкой/записью байткода, обратитесь к importlib.abc.SourceLoader.

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

importlib.util.cache_from_source(path, debug_override=None, *, optimization=None)

Возвращает путь PEP 3147/PEP 488 к файлу с байт-компилированным кодом, связанному с исходным путём path. Например, если path равен /foo/bar/baz.py, то значением возврата будет /foo/bar/__pycache__/baz.cpython-32.pyc, для Python 3.2. Строка cpython-32 взята из текущей метки магической строки (см. get_tag(); если sys.implementation.cache_tag не определено, то будет вызвано исключение NotImplementedError).

Параметр optimization используется для указания уровня оптимизации файла байткода. Пустая строка означает отсутствие оптимизации, поэтому /foo/bar/baz.py с optimization равным '' приведет к пути байткода /foo/bar/__pycache__/baz.cpython-32.pyc. None использует уровень оптимизации интерпретатора. Любое другое значение будет использоваться в виде строки, поэтому /foo/bar/baz.py с optimization равным 2 приведет к пути байткода /foo/bar/__pycache__/baz.cpython-32.opt-2.pyc. Строковое представление optimization может содержать только буквенно-цифровые символы, иначе будет вызвано исключение ValueError.

Параметр debug_override устарел и может использоваться для переопределения системного значения для __debug__. Значение True эквивалентно установке optimization в пустую строку. Значение False равно установке optimization в 1. Если ни debug_override, ни optimization не None, будет вызвано исключение TypeError.

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

Изменено в версии 3.5: Добавлен параметр optimization, параметр debug_override устарел.

Изменено в версии 3.6: Принимает объект-путь.

importlib.util.source_from_cache(path)

Учитывая путь к имени файла PEP 3147, возвращает путь к соответствующему исходному файлу. Например, если path равен /foo/bar/__pycache__/baz.cpython-32.pyc, возвращаемый путь будет /foo/bar/baz.py. path необязательно должен существовать, однако, если он не соответствует формату PEP 3147 или PEP 488, будет поднято исключение ValueError. Если sys.implementation.cache_tag не определено, будет поднято исключение NotImplementedError.

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

Изменено в версии 3.6: Принимает объект-путь.

importlib.util.decode_source(source_bytes)

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

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

importlib.util.resolve_name(name, package)

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

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

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

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

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

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

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

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

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

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

Изменено в версии 3.7: Генерирует исключение 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 используется для установки как можно большего количества контролируемых импортом атрибутов в модуле.

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

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

Функция-фабрика для создания экземпляра ModuleSpec на основе загрузчика. Параметры имеют тот же смысл, что и для ModuleSpec. Функция использует доступные API загрузчика, такие как InspectLoader.is_package(), для заполнения любой отсутствующей информации в спецификации.

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

END_OF_DOCUMENT_MARKER
importlib.util.spec_from_file_location(name, location, *, loader=None, submodule_search_locations=None)

Функция-фабрика для создания экземпляра ModuleSpec на основе пути к файлу. Отсутствующая информация будет добавлена в спецификацию с использованием API загрузчика и из предположения, что модуль будет основан на файле.

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

Изменён в версии 3.6: Принимает объект, подобный пути.

importlib.util.source_hash(source_bytes)

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

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

importlib.util._incompatible_extension_module_restrictions(*, disable_check)

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

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

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

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

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

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

class importlib.util.LazyLoader(loader)

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

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

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

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

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

import importlib.util
import sys


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


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

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

Реализация ленивых импортов

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

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

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

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

import importlib.machinery
import sys

# For illustrative purposes only.
SpamMetaPathFinder = importlib.machinery.PathFinder
SpamPathEntryFinder = importlib.machinery.FileFinder
loader_details = (importlib.machinery.SourceFileLoader,
                  importlib.machinery.SOURCE_SUFFIXES)

# Setting up a meta path finder.
# Make sure to put the finder in the proper location in the list in terms of
# priority.
sys.meta_path.append(SpamMetaPathFinder)

# Setting up a path entry finder.
# Make sure to put the path hook in the proper location in the list in terms
# of priority.
sys.path_hooks.append(SpamPathEntryFinder.path_hook(loader_details))

Приблизительная реализация importlib.import_module()

Сам импорт реализован на языке Python, что позволяет получить доступ к большей части механизма импорта через importlib. Следующее помогает проиллюстрировать различные API, которые importlib предоставляет, предоставив приблизительную реализацию importlib.import_module():

import importlib.util
import sys

def import_module(name, package=None):
    """An approximate implementation of import."""
    absolute_name = importlib.util.resolve_name(name, package)
    try:
        return sys.modules[absolute_name]
    except KeyError:
        pass

    path = None
    if '.' in absolute_name:
        parent_name, _, child_name = absolute_name.rpartition('.')
        parent_module = import_module(parent_name)
        path = parent_module.__spec__.submodule_search_locations
    for finder in sys.meta_path:
        spec = finder.find_spec(absolute_name, path)
        if spec is not None:
            break
    else:
        msg = f'No module named {absolute_name!r}'
        raise ModuleNotFoundError(msg, name=absolute_name)
    module = importlib.util.module_from_spec(spec)
    sys.modules[absolute_name] = module
    spec.loader.exec_module(module)
    if path is not None:
        setattr(parent_module, child_name, module)
    return module

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

Spec-Zone.ru

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