imp — Доступ к внутренним компонентам import

Не рекомендуется, начиная с версии 3.4: Модуль imp устарел в пользу importlib.


Данный модуль предоставляет интерфейс для механизмов, используемых для реализации инструкции import. Он определяет следующие константы и функции:

imp.get_magic()

Возвращает магическое строковое значение, используемое для распознавания файлов кода с байтовой компиляцией (файлы .pyc). (Это значение может быть разным для каждой версии Python.)

Не рекомендуется, начиная с версии 3.4: Вместо нее используйте importlib.util.MAGIC_NUMBER.

imp.get_suffixes()

Возвращает список кортежей из 3 элементов, каждый из которых определяет определённый тип модуля. Каждая тройка имеет форму (suffix, mode, type), где suffix — это строка, добавляемая к имени модуля для формирования имени файла для поиска, mode — это строка режима, передаваемая встроенной функции open() для открытия файла (это может быть 'r' для текстовых файлов или 'rb' для двоичных файлов), а type — это тип файла, у которого одно из значений PY_SOURCE, PY_COMPILED или C_EXTENSION, рассмотренных далее.

Не рекомендуется, начиная с версии 3.3: Вместо нее используйте константы, определённые в importlib.machinery.

imp.find_module(name[, path])

Пытается найти модуль name. Если path пропущен или None, выполняется поиск в списке имён каталогов, заданном sys.path, но сначала выполняется поиск в нескольких специальных местах: функция пытается найти встроенный модуль с заданным именем (C_BUILTIN), затем замороженный модуль ( PY_FROZEN), а в некоторых системах также просматриваются некоторые другие места (в Windows он просматривается в реестре, который может указывать на определённый файл).

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

В случае успешного поиска возвращается кортеж из трёх элементов (file, pathname, description):

file — расположенный в начале открытый файловый объект, pathname — путь к найденному файлу, а description — трехэлементный кортеж, содержащийся в списке, возвращаемом get_suffixes(), описывающим тип найденного модуля.

Если модуль встроен или заморожен, то file и pathname оба являются None, а кортеж description содержит пустые строки для своего суффикса и режима; тип модуля указан в скобках выше. Если поиск не увенчался успехом, вызывается ImportError. Другие исключения указывают на проблемы с аргументами или средой.

Если модуль представляет собой пакет, file — это None, pathname — это путь к пакету, а последний элемент в кортеже description — это PKG_DIRECTORY.

Данная функция не обрабатывает иерархические имена модулей (имена, содержащие точки). Чтобы найти P.M, т. е. подмодуль M пакета P, используйте find_module() и load_module(), чтобы найти и загружает пакет P, а затем используйте find_module() с аргументом path, установленным в P.__path__. Когда у P есть имя с точкой, данный рецепт применяется рекурсивно.

Не рекомендуется, начиная с версии 3.3: Вместо нее используйте importlib.util.find_spec(), если не требуется совместимость с Python 3.3, и в этом случае используйте importlib.find_loader(). Например, использование первого случая см. в разделе Примеры документации importlib.

imp.load_module(name, file, pathname, description)

Загружает модуль, ранее найденный с помощью find_module() (или с помощью другого поиска, дающего совместимые результаты). Данная функция делает больше, чем просто импортирует модуль: если модуль уже был импортирован, он будет перезагружен! Аргумент name указывает полное имя модуля (включая имя пакета, если это подмодуль пакета). Аргумент file — это открытый файл, а pathname — соответствующее имя файла; это могут быть None и '' соответственно, когда модуль представляет собой пакет или не загружается из файла. Аргумент description — это кортеж, возвращаемый get_suffixes(), описывающий, какой модуль должен быть загружен.

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

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

Не рекомендуется, начиная с версии 3.3: Если ранее он использовался вместе с imp.find_module(), рассмотрите возможность использования importlib.import_module(), в противном случае используйте загрузчик, возвращённый заменой, которую вы выбрали для imp.find_module(). Если вы вызвали imp.load_module() и связанные функции напрямую с аргументами пути к файлу, используйте комбинацию importlib.util.spec_from_file_location() и importlib.util.module_from_spec(). Подробнее о различных подходах см. в разделе Примеры документации importlib.

imp.new_module(name)

Возвращает новый пустой объект модуля с именем name. Данный объект не имеет номер, вставленный в sys.modules.

Не рекомендуется, начиная с версии 3.4: Вместо этого используйте importlib.util.module_from_spec().

imp.reload(module)

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

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

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

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

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

try:
    cache
except NameError:
    cache = {}

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

Если модуль импортирует объекты из другого модуля, используя fromimport …, вызов reload() для другого модуля не переопределяет импортированные из него объекты —. import и полные имена (module.*name*).

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

Изменено в версии 3.3: Полагается на то, что __name__ и __loader__ определены для перезагружаемого модуля, а не только __name__.

Не рекомендуется, начиная с версии 3.4: Вместо этого используйте importlib.reload().

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

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

imp.cache_from_source(path, debug_override=None)

Возвращает путь PEP 3147 к байт-компилированному файлу, связанному с источником 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). Передав True или False для debug_override, вы можете переопределить системное значение для __debug__, что приведёт к оптимизации байт-кода.

path не обязательно должен существовать.

Изменено в версии 3.3: Если sys.implementation.cache_tag равен None, то вызывается NotImplementedError.

Не рекомендуется, начиная с версии 3.4: Вместо нее используйте importlib.util.cache_from_source().

Изменено в версии 3.5: Параметр debug_override больше не создаёт файл .pyo.

imp.source_from_cache(path)

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

Изменено в версии 3.3: Вызывается NotImplementedError, если sys.implementation.cache_tag не определён.

Не рекомендуется, начиная с версии 3.4: Вместо нее используйте importlib.util.source_from_cache().

imp.get_tag()

Возвращает строку магического тега PEP 3147, соответствующую этой версии магического числа Python, возвращенную get_magic().

Не рекомендуется, начиная с версии 3.4: Используйте sys.implementation.cache_tag непосредственно, начиная с Python 3.3.

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

imp.lock_held()

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

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

Изменено в версии 3.3: Схема блокировки по большей части изменилась на помодульные блокировки. Глобальная блокировка импорта сохраняется для некоторых важных задач, таких как инициализация блокировок для каждого модуля.

Не рекомендуется, начиная с версии 3.4.

imp.acquire_lock()

Получает глобальную блокировку импорта интерпретатора для текущего потока. Блокировка должна использоваться перехватчиками импорта для обеспечения потокобезопасности при импорте модулей.

Как только поток получил блокировку импорта, тот же поток может снова получить её без блокировки; поток должен освобождать его один раз каждый раз, когда он его получает.

На платформах без потоков данная функция ничего не делает.

Изменено в версии 3.3: Схема блокировки по большей части изменилась на помодульные блокировки. Глобальная блокировка импорта сохраняется для некоторых важных задач, таких как инициализация блокировок для каждого модуля.

Не рекомендуется, начиная с версии 3.4.

imp.release_lock()

Снимает глобальную блокировку импорта интерпретатора. На платформах без потоков данная функция ничего не делает.

Изменено в версии 3.3: Схема блокировки по большей части изменилась на помодульные блокировки. Глобальная блокировка импорта сохраняется для некоторых важных задач, таких как инициализация блокировок для каждого модуля.

Не рекомендуется, начиная с версии 3.4.

Следующие константы с целочисленными значениями, определённые в этом модуле, используются для указания результата поиска find_module().

imp.PY_SOURCE

Модуль был найден как исходный файл.

Не рекомендуется, начиная с версии 3.3.

imp.PY_COMPILED

Модуль был найден как объектный файл скомпилированного кода.

Не рекомендуется, начиная с версии 3.3.

imp.C_EXTENSION

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

Не рекомендуется, начиная с версии 3.3.

imp.PKG_DIRECTORY

Модуль был найден как каталог пакета.

Не рекомендуется, начиная с версии 3.3.

imp.C_BUILTIN

Модуль был найден как встроенный модуль.

Не рекомендуется, начиная с версии 3.3.

imp.PY_FROZEN

Модуль был найден как замороженный модуль.

Не рекомендуется, начиная с версии 3.3.

class imp.NullImporter(path_string)

Тип NullImporter — это обработчик импорта PEP 302, который обрабатывает строки пути, не относящиеся к каталогу, поскольку не может найти какие-либо модули. Вызов этого типа с существующим каталогом или пустой строкой вызывает ImportError. В противном случае возвращается экземпляр NullImporter.

Экземпляры имеют только один метод:

find_module(fullname[, path])

Данный метод всегда возвращает None, указывая на то, что запрошенный модуль не может быть найден.

Изменено в версии 3.3: None передается в sys.path_importer_cache вместо экземпляра NullImporter.

Не рекомендуется, начиная с версии 3.4: Вместо него передается None в sys.path_importer_cache.

Примеры

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

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Быстрый путь: проверяет, был ли модуль уже импортирован.
    try:
        return sys.modules[name]
    except KeyError:
        pass

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

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Поскольку мы можем выйти через исключение, закрываем fp явно.
        if fp:
            fp.close()