Spec-Zone.ru › Python 3.13

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

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

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

Введение

Пакет importlib предназначен для решения трёх задач.

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

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

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

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

См. также

Оператор import

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

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

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

The __import__() function

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

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

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

PEP 235

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

PEP 263

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

PEP 302

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

PEP 328

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

PEP 366

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

PEP 420

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

PEP 451

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

PEP 488

Отказ от файлов PYO

PEP 489

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

PEP 552

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

PEP 3120

Использование UTF-8 в качестве кодировки исходного кода по умолчанию

PEP 3147

Каталоги репозитория PYC

Функции

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)

Реализация встроенной функции __import__().

Примечание

Для программного импорта модулей следует использовать import_module(), а не эту функцию.

importlib.import_module(name, package=None)

Импортирует модуль. Аргумент name задаёт модуль для импорта в абсолютной или относительной форме (например, pkg.mod или ..mod). Если имя задано в относительной форме, аргумент package должен содержать имя пакета, который будет служить точкой отсчёта для разрешения имени пакета (например, import_module('..mod', 'pkg.subpkg') импортирует pkg.mod).

Функция import_module() является упрощённой обёрткой для importlib.__import__(). Это означает, что вся семантика функции определяется функцией importlib.__import__(). Самое важное различие между этими двумя функциями состоит в том, что import_module() возвращает указанный пакет или модуль (например, pkg.mod), а __import__() возвращает пакет или модуль верхнего уровня (например, pkg).

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

Изменено в версии 3.3: Родительские пакеты импортируются автоматически.

importlib.invalidate_caches()

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

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

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

importlib.reload(module)

Повторно загружает ранее импортированный 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.

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

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

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

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

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

Иерархия ABC:

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

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

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

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

find_spec(fullname, path, target=None)

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

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

invalidate_caches()

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

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

class importlib.abc.PathEntryFinder

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

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

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

find_spec(fullname, target=None)

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

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

invalidate_caches()

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

class importlib.abc.Loader

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

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

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

create_module(spec)

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

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

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

exec_module(module)

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

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

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

load_module(fullname)

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

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

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

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

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

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

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

class importlib.abc.ResourceLoader

Заменён на TraversableResources

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

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

abstractmethod get_data(path)

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

Изменено в версии 3.4: Возбуждает исключение OSError вместо NotImplementedError.

class importlib.abc.InspectLoader

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

get_code(fullname)

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

Примечание

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

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

abstractmethod get_source(fullname)

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

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

is_package(fullname)

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

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

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

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

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

Полученный объект кода можно выполнить в модуле, запустив exec(code, module.__dict__).

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

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

exec_module(module)

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

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

load_module(fullname)

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

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

class importlib.abc.ExecutionLoader

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

abstractmethod get_filename(fullname)

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

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

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

class importlib.abc.FileLoader(fullname, path)

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

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

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

name

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

path

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

load_module(fullname)

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

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

abstractmethod get_filename(fullname)

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

abstractmethod get_data(path)

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

class importlib.abc.SourceLoader

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

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

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

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

path_stats(path)

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

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

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

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

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

path_mtime(path)

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

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

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

set_data(path, data)

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

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

Изменено в версии 3.4: При вызове больше не вызывается исключение NotImplementedError.

get_code(fullname)

Готовая реализация InspectLoader.get_code().

exec_module(module)

Готовая реализация Loader.exec_module().

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

load_module(fullname)

Готовая реализация Loader.load_module().

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

get_source(fullname)

Готовая реализация InspectLoader.get_source().

is_package(fullname)

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

class importlib.abc.ResourceReader

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

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

С точки зрения этого ABC, ресурс — это двоичный артефакт, поставляемый внутри пакета. Обычно это файл данных, расположенный рядом с файлом __init__.py пакета. Этот класс предназначен для абстрагирования доступа к таким файлам данных, чтобы не имело значения, где хранятся пакет и его файлы данных — например, в ZIP-файле или в файловой системе.

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

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

Добавлено в версии 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() возвращал бы False.

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

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

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 в self.

abstractmethod open(mode='r', *args, **kwargs)

Для открытия в текстовом или двоичном режиме параметр mode может принимать значение ‘r’ или ‘rb’. Возвращает дескриптор, пригодный для чтения (аналогично pathlib.Path.open).

При открытии в текстовом режиме принимает параметры кодировки, такие как параметры io.TextIOWrapper.

read_bytes()

Читает содержимое self в виде байтов.

read_text(encoding=None)

Читает содержимое self в виде текста.

class importlib.abc.TraversableResources

Абстрактный базовый класс для считывателей ресурсов, поддерживающих интерфейс importlib.resources.files(). Наследует importlib.resources.abc.ResourceReader и предоставляет готовые реализации абстрактных методов importlib.resources.abc.ResourceReader. Поэтому любой загрузчик, предоставляющий importlib.abc.TraversableResources, также предоставляет ResourceReader.

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

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

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

abstractmethod files()

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

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

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

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

importlib.machinery.SOURCE_SUFFIXES

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

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

importlib.machinery.DEBUG_BYTECODE_SUFFIXES

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

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

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

importlib.machinery.OPTIMIZED_BYTECODE_SUFFIXES

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

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

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

importlib.machinery.BYTECODE_SUFFIXES

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

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

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

importlib.machinery.EXTENSION_SUFFIXES

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

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

importlib.machinery.all_suffixes()

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

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

class importlib.machinery.BuiltinImporter

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

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

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

class importlib.machinery.FrozenImporter

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

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

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

class importlib.machinery.WindowsRegistryFinder

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

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

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

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

class importlib.machinery.PathFinder

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

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

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

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

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

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

classmethod invalidate_caches()

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

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

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

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

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

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

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

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

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

path

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

find_spec(fullname, target=None)

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

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

invalidate_caches()

Очищает внутренний кэш.

classmethod path_hook(*loader_details)

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

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

class importlib.machinery.SourceFileLoader(fullname, path)

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

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

name

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

path

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

is_package(fullname)

Возвращает True, если path указывает на пакет.

path_stats(path)

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

set_data(path, data)

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

load_module(name=None)

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

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

class importlib.machinery.SourcelessFileLoader(fullname, path)

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

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

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

name

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

path

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

is_package(fullname)

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

get_code(fullname)

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

get_source(fullname)

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

load_module(name=None)

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

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

class importlib.machinery.ExtensionFileLoader(fullname, path)

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

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

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

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

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

name

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

path

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

create_module(spec)

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

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

exec_module(module)

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

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

is_package(fullname)

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

get_code(fullname)

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

get_source(fullname)

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

get_filename(fullname)

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

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

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

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

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

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

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

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

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

name

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

loader

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

origin

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

submodule_search_locations

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

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

loader_state

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

cached

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

parent

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

has_location

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

class importlib.machinery.AppleFrameworkLoader(name, path)

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

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

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

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

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

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

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

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

name

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

path

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

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

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

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

importlib.util.MAGIC_NUMBER

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

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

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

Возвращает путь в формате PEP 3147/PEP 488 к файлу с байткодом, связанному с исходным файлом по пути path. Например, если path равен /foo/bar/baz.py, для Python 3.2 возвращаемым значением будет /foo/bar/__pycache__/baz.cpython-32.pyc. Строка 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 равнозначно установке 1 для optimization. Если и debug_override, и optimization не равны None, вызывается исключение TypeError.

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

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

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

importlib.util.source_from_cache(path)

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

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

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

importlib.util.decode_source(source_bytes)

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

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

importlib.util.resolve_name(name, package)

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

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

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

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

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

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

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

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

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

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

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

importlib.util.module_from_spec(spec)

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

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

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

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

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

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

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

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

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

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

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

importlib.util.source_hash(source_bytes)

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

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

importlib.util._incompatible_extension_module_restrictions(*, disable_check)

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

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

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

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

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

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

class importlib.util.LazyLoader(loader)

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

Этот класс работает только с загрузчиками, определяющими exec_module(), поскольку необходимо контролировать тип модуля. По тем же причинам метод create_module() загрузчика должен возвращать None либо тип, у которого можно изменять атрибут __class__, а также не использовать слоты. Наконец, модули, заменяющие объект, помещенный в sys.modules, работать не будут, поскольку невозможно безопасно и корректно заменить ссылки на модуль во всем интерпретаторе; при обнаружении такой подмены вызывается исключение ValueError.

Примечание

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

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

Изменено в версии 3.6: Начал вызывать create_module(); предупреждение о несовместимости для importlib.machinery.BuiltinImporter и importlib.machinery.ExtensionFileLoader удалено.

classmethod factory(loader)

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

suffixes = importlib.machinery.SOURCE_SUFFIXES
loader = importlib.machinery.SourceFileLoader
lazy_loader = importlib.util.LazyLoader.factory(loader)
finder = importlib.machinery.FileFinder(path, (lazy_loader, suffixes))

Примеры

Программный импорт

Для программного импорта модуля используйте importlib.import_module().

import importlib

itertools = importlib.import_module('itertools')

Проверка возможности импорта модуля

Если нужно выяснить, можно ли импортировать модуль, не выполняя сам импорт, используйте importlib.util.find_spec().

Обратите внимание: если name — это подмодуль (содержит точку), importlib.util.find_spec() импортирует родительский модуль.

import importlib.util
import sys

# For illustrative purposes.
name = 'itertools'

if name in sys.modules:
    print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
    # If you chose to perform the actual import ...
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    print(f"{name!r} has been imported")
else:
    print(f"can't find the {name!r} module")

Непосредственный импорт исходного файла

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

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

import importlib.util
import sys


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


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

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

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

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

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

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

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

import importlib.machinery
import sys

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

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

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

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

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

import importlib.util
import sys

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

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

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

Spec-Zone.ru

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