imp
— Доступ к внутренним компонентам import¶
Исходный код: Lib/imp.py.
Этот модуль предоставляет интерфейс к механизмам, используемым для реализации оператора import
. Он определяет следующие константы и функции:
-
imp.
get_magic
()¶ Возвращает значение магической строки, используемое для распознавания файлов байт-компилированного кода (файлы
.pyc
). (Это значение может быть разным для каждой версии Python).Не рекомендуется, начиная с версии 3.4: Вместо этого используйте
importlib.util.MAGIC_NUMBER
.
-
imp.
get_suffixes
()¶ Возвращает список трехэлементных кортежей, каждый из которых описывает определенный тип модуля. Каждая тройка имеет вид
(suffix, mode, type)
, где suffix - это строка, которая будет добавлена к имени модуля для формирования имени файла для поиска, mode - это строка 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 - открытый file object, расположенный в начале, 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
, даже если возникло исключение. Это лучше всего сделать с помощью оператораtry
…finally
.Не рекомендуется, начиная с версии 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)¶ Перезагрузить ранее импортированный модуль. Аргумент должен быть объектом модуля, поэтому он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля с помощью внешнего редактора и хотите опробовать новую версию, не выходя из интерпретатора Python. Возвращаемое значение - объект модуля (такой же, как аргумент module).
Когда выполняется
reload(module)
:Код модулей Python перекомпилируется и код на уровне модуля выполняется заново, определяя новый набор объектов, которые привязываются к именам в словаре модуля. Функция
init
модулей расширения не вызывается второй раз.Как и все другие объекты в Python, старые объекты восстанавливаются только после того, как количество ссылок на них упадет до нуля.
Имена в пространстве имен модуля обновляются, чтобы указать на все новые или измененные объекты.
Другие ссылки на старые объекты (например, имена, внешние по отношению к модулю) не могут ссылаться на новые объекты и должны быть обновлены в каждом пространстве имен, где они встречаются, если это необходимо.
Есть и ряд других предостережений:
Когда модуль перезагружается, его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределения имен отменяют старые определения, поэтому обычно это не является проблемой. Если в новой версии модуля не определено имя, которое было определено в старой версии, то старое определение сохраняется. Эта возможность может быть использована в интересах модуля, если он поддерживает глобальную таблицу или кэш объектов — с помощью оператора
try
можно проверить наличие таблицы и пропустить ее инициализацию при желании:try: cache except NameError: cache = {}
Перезагрузка встроенных или динамически загружаемых модулей, за исключением
sys
,__main__
иbuiltins
, является законной, хотя обычно не очень полезной. Во многих случаях, однако, модули расширения не предназначены для инициализации более одного раза, и при перезагрузке могут дать произвольный сбой.Если модуль импортирует объекты из другого модуля с помощью
from
…import
…, вызовreload()
для другого модуля не переопределяет импортированные из него объекты — одним из способов обойти это является повторное выполнение оператораfrom
, другим - использование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__
, что приведет к оптимизированному байткоду.путь не обязательно должен существовать.
Изменено в версии 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)¶ Учитывая путь к имени файла 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: Начиная с Python 3.3, используйте
sys.implementation.cache_tag
напрямую.
Следующие функции помогают взаимодействовать с внутренним механизмом блокировки системы импорта. Семантика блокировки импорта - это деталь реализации, которая может меняться от выпуска к выпуску. Однако 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):
# Fast path: see if the module has already been imported.
try:
return sys.modules[name]
except KeyError:
pass
# If any of the following calls raises an exception,
# there's a problem we can't handle -- let the caller handle it.
fp, pathname, description = imp.find_module(name)
try:
return imp.load_module(name, fp, pathname, description)
finally:
# Since we may exit via an exception, close fp explicitly.
if fp:
fp.close()