Содержание страницы
imp – Доступ к внутренностям import¶imp – Access the import internals
Этот модуль предоставляет интерфейс к механизмам, используемым для реализации оператора import. Он определяет следующие константы и функции:
Примечание
В новых программах вместо этого модуля следует использовать importlib.
- imp.get_magic()¶
Возвращает магическое строковое значение, используемое для распознавания байт-кодовых файлов (файлов .pyc). (Это значение может различаться для разных версий Python.)
- imp.get_suffixes()¶
Возвращает список трёхэлементных кортежей, каждый из которых описывает конкретный тип модуля. Каждая тройка имеет вид (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 равен None, pathname – пустая строка, а кортеж 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.find_loader().
- imp.load_module(name, file, pathname, description)¶
Загружает модуль, который ранее был найден с помощью find_module() (или другого поиска, давшего совместимые результаты). Эта функция делает больше, чем просто импорт модуля: если модуль уже был импортирован, она перезагружает его! Аргумент name указывает полное имя модуля (включая имя пакета, если это подмодуль пакета). Аргумент file – это открытый файл, а pathname – соответствующее имя файла; они могут быть None и '' соответственно, когда модуль является пакетом или не загружается из файла. Аргумент description – это кортеж, такой, какой вернула бы get_suffixes(), описывающий, какой тип модуля должен быть загружен.
Если загрузка успешна, возвращается объект модуля; в противном случае возбуждается исключение (обычно ImportError).
Важно: вызывающий код отвечает за закрытие аргумента file, если он не был None, даже при возбуждении исключения. Лучше всего это делать с помощью оператора try ... finally.
Устарело с версии 3.3: Больше не нужна, так как для загрузки модулей следует использовать загрузчики, а find_module() устарела.
- imp.new_module(name)¶
Возвращает новый пустой объект модуля с именем name. Этот объект не вставляется в sys.modules.
- imp.reload(module)¶
Перезагружает ранее импортированный модуль module. Аргумент должен быть объектом модуля, то есть он должен быть успешно импортирован ранее. Это полезно, если вы отредактировали исходный файл модуля во внешнем редакторе и хотите опробовать новую версию, не выходя из интерпретатора Python. Возвращаемое значение – объект модуля (тот же, что и аргумент module).
При выполнении reload(module):
- Код модулей Python перекомпилируется, и код уровня модуля выполняется заново, определяя новый набор объектов, которые привязываются к именам в словаре модуля. Функция init модулей расширения не вызывается второй раз.
- Как и в случае со всеми другими объектами в Python, старые объекты освобождаются только после того, как их счётчики ссылок упадут до нуля.
- Имена в пространстве имён модуля обновляются, чтобы указывать на любые новые или изменённые объекты.
- Другие ссылки на старые объекты (например, имена вне модуля) не перепривязываются для указания на новые объекты и должны быть обновлены в каждом пространстве имён, где они встречаются, если это необходимо.
Существует ряд других предостережений:
Если модуль синтаксически корректен, но его инициализация завершается ошибкой, первый оператор import для него не связывает имя локально, но сохраняет (частично инициализированный) объект модуля в sys.modules. Чтобы перезагрузить модуль, сначала нужно снова выполнить import (это свяжет имя с частично инициализированным объектом модуля), и только затем можно вызвать для него reload().
При перезагрузке модуля его словарь (содержащий глобальные переменные модуля) сохраняется. Переопределения имён заменяют старые определения, так что обычно это не проблема. Если новая версия модуля не определяет имя, которое было определено в старой версии, старое определение остаётся. Эту возможность можно использовать в пользу модуля, если он поддерживает глобальную таблицу или кеш объектов – с помощью оператора try он может проверить наличие таблицы и, если нужно, пропустить её инициализацию:
try: cache except NameError: cache = {}
Перезагружать встроенные или динамически загружаемые модули допустимо, хотя обычно не очень полезно, за исключением sys, __main__ и builtins. Однако во многих случаях модули расширения не предназначены для инициализации более одного раза и могут произвольно аварийно завершаться при перезагрузке.
Если модуль импортирует объекты из другого модуля с помощью from ... import ..., то вызов reload() для другого модуля не переопределяет импортированные из него объекты. Один из способов обойти это – повторно выполнить оператор from, другой – использовать import и квалифицированные имена (module.*name*).
Если модуль создаёт экземпляры класса, перезагрузка модуля, определяющего класс, не влияет на определения методов экземпляров – они продолжают использовать старое определение класса. То же самое верно для производных классов.
Изменено в версии 3.3: Теперь полагается на то, что в перезагружаемом модуле определены как __name__, так и __loader__, а не только __name__.
Следующие функции предоставляют удобные средства для работы с путями к PEP 3147 скомпилированным в байт-код файлам.
Новое в версии 3.2.
- imp.cache_from_source(path, debug_override=None)¶
Возвращает путь в формате PEP 3147 к файлу с байт-кодом, соответствующему исходному файлу path. Например, если path – это /foo/bar/baz.py, то для Python 3.2 возвращаемое значение будет /foo/bar/__pycache__/baz.cpython-32.pyc. Строка cpython-32 берётся из текущего magic-тега (см. get_tag(); если sys.implementation.cache_tag не определён, то будет возбуждено NotImplementedError). Возвращаемый путь будет заканчиваться на .pyc, когда __debug__ равно True, или на .pyo для оптимизированного Python (т.е. __debug__ равно False). Передавая True или False в debug_override, можно переопределить системное значение __debug__ для выбора расширения.
path не обязан существовать.
Изменено в версии 3.3: Если sys.implementation.cache_tag равен None, то возбуждается NotImplementedError.
- 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 не определён.
- imp.get_tag()¶
Возвращает строку magic-тега в формате PEP 3147, соответствующую magic-числу данной версии Python, как возвращается get_magic().
Примечание
Начиная с Python 3.3, можно напрямую использовать sys.implementation.cache_tag.
Следующие функции помогают взаимодействовать с внутренним механизмом блокировок системы импорта. Семантика блокировок импорта является деталью реализации, которая может меняться от версии к версии. Однако Python гарантирует, что циклические импорты работают без взаимных блокировок.
- imp.lock_held()¶
Возвращает True, если глобальная блокировка импорта в данный момент удерживается, иначе False. На платформах без потоков всегда возвращает False.
На платформах с потоками поток, выполняющий импорт, сначала удерживает глобальную блокировку импорта, затем устанавливает блокировку на каждый модуль для остальной части импорта. Это блокирует другие потоки от импорта того же модуля до завершения исходного импорта, предотвращая появление у других потоков неполных объектов модуля, созданных исходным потоком. Исключение делается для циклических импортов, которые по своей природе должны в какой-то момент предоставить неполный объект модуля.
Изменено в версии 3.3: Схема блокировки в основном изменилась на блокировки для каждого модуля. Глобальная блокировка импорта сохраняется для некоторых критических задач, таких как инициализация блокировок отдельных модулей.
- imp.acquire_lock()¶
Захватывает глобальную блокировку импорта интерпретатора для текущего потока. Эта блокировка должна использоваться хуками импорта для обеспечения потокобезопасности при импорте модулей.
После того как поток захватил блокировку импорта, тот же поток может захватить её снова без блокировки; поток должен освобождать её один раз за каждый захват.
На платформах без потоков эта функция ничего не делает.
Изменено в версии 3.3: Схема блокировки в основном изменилась на блокировки для каждого модуля. Глобальная блокировка импорта сохраняется для некоторых критических задач, таких как инициализация блокировок отдельных модулей.
- imp.release_lock()¶
Освобождает глобальную блокировку импорта интерпретатора. На платформах без поддержки потоков эта функция ничего не делает.
Изменено в версии 3.3: Схема блокировки в основном изменилась на блокировки для каждого модуля. Глобальная блокировка импорта сохраняется для некоторых критических задач, таких как инициализация блокировок отдельных модулей.
Следующие константы с целочисленными значениями, определённые в этом модуле, используются для указания результата поиска 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: В sys.path_importer_cache теперь вставляется None вместо экземпляра NullImporter.
30.1.1. Примеры¶Examples
Следующая функция эмулирует то, что было стандартным оператором импорта до 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()