imp.md
1> **Источник:** https://python-all.ru/2.7/library/imp.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 31.1. [`imp`](https://python-all.ru/2.7/library/imp.html#module-imp) – Доступ к [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import)внутренним механизмам89Этот модуль предоставляет интерфейс к механизмам, используемым для реализации оператора [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import). Он определяет следующие константы и функции:1011#### `imp.get_magic()`1213Возвращает строку магического значения, используемую для распознавания файлов с байт-кодом (файлы `.pyc`). (Это значение может отличаться для разных версий Python.)1415#### `imp.get_suffixes()`1617Возвращает список кортежей из 3 элементов, каждый из которых описывает определённый тип модуля. Каждый кортеж имеет вид `(suffix, mode, type)`, где *suffix* – это строка, добавляемая к имени модуля для получения имени файла для поиска, *mode* – строка режима, передаваемая встроенной функции [`open()`](https://python-all.ru/2.7/library/functions.html#open) для открытия файла (это может быть `'r'` для текстовых файлов или `'rb'` для двоичных файлов), а *type* – тип файла, который может принимать одно из значений [`PY_SOURCE`](https://python-all.ru/2.7/library/imp.html#imp.PY_SOURCE), [`PY_COMPILED`](https://python-all.ru/2.7/library/imp.html#imp.PY_COMPILED) или [`C_EXTENSION`](https://python-all.ru/2.7/library/imp.html#imp.C_EXTENSION), описанных ниже.1819#### `imp.find_module(name[, path])`2021Пытается найти модуль *name*. Если *path* опущен или `None`, выполняется поиск по списку имён каталогов, указанному в `sys.path`, но сначала проверяется несколько особых мест: функция пытается найти встроенный модуль с заданным именем ([`C_BUILTIN`](https://python-all.ru/2.7/library/imp.html#imp.C_BUILTIN)), затем замороженный модуль ([`PY_FROZEN`](https://python-all.ru/2.7/library/imp.html#imp.PY_FROZEN)), а на некоторых системах также проверяются другие места (в Windows выполняется поиск в реестре, который может указывать на конкретный файл).2223В противном случае *path* должен быть списком имён каталогов; каждый каталог проверяется на наличие файлов с любым из суффиксов, возвращаемых [`get_suffixes()`](https://python-all.ru/2.7/library/imp.html#imp.get_suffixes) выше. Недопустимые имена в списке игнорируются (но все элементы списка должны быть строками).2425Если поиск успешен, возвращаемое значение – кортеж из 3 элементов `(file, pathname, description)`:2627*file* – это открытый файловый объект, расположенный в начале, *pathname* – это путь к найденному файлу, а *description* – это кортеж из 3 элементов, как содержится в списке, возвращаемом [`get_suffixes()`](https://python-all.ru/2.7/library/imp.html#imp.get_suffixes), описывающий тип найденного модуля.2829Если модуль не находится в файле, возвращаемый *file* равен `None`, *pathname* – пустая строка, а кортеж *description* содержит пустые строки для его suffix и mode; тип модуля указывается так, как приведено в скобках выше. Если поиск неуспешен, возбуждается [`ImportError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ImportError). Другие исключения указывают на проблемы с аргументами или окружением.3031Если модуль является пакетом, *file* равен `None`, *pathname* – это путь к пакету, а последний элемент кортежа *description* равен [`PKG_DIRECTORY`](https://python-all.ru/2.7/library/imp.html#imp.PKG_DIRECTORY).3233Эта функция не обрабатывает иерархические имена модулей (имена, содержащие точки). Чтобы найти *P.M*, то есть подмодуль *M* пакета *P*, используйте [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module) и [`load_module()`](https://python-all.ru/2.7/library/imp.html#imp.load_module) для поиска и загрузки пакета *P*, а затем используйте [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module) с аргументом *path*, установленным в `P.__path__`. Когда *P* сам имеет составное имя, применяйте этот рецепт рекурсивно.3435#### `imp.load_module(name, file, pathname, description)`3637Загружает модуль, ранее найденный с помощью [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module) (или в результате другого поиска, давшего совместимые результаты). Эта функция делает больше, чем просто импорт модуля: если модуль уже был импортирован, она эквивалентна вызову [`reload()`](https://python-all.ru/2.7/library/functions.html#reload)! Аргумент *name* указывает полное имя модуля (включая имя пакета, если это подмодуль пакета). Аргумент *file* – это открытый файл, а *pathname* – соответствующее имя файла; они могут быть `None` и `''` соответственно, если модуль является пакетом или не загружается из файла. Аргумент *description* – это кортеж, как возвращаемый [`get_suffixes()`](https://python-all.ru/2.7/library/imp.html#imp.get_suffixes), описывающий, какой именно модуль должен быть загружен.3839Если загрузка успешна, возвращается объект модуля; в противном случае возбуждается исключение (обычно [`ImportError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ImportError)).4041**Важно:** вызывающая сторона обязана закрыть аргумент *file*, если он не равен `None`, даже при возникновении исключения. Это лучше всего сделать с помощью оператора [`try`](https://python-all.ru/2.7/reference/compound_stmts.html#try) … [`finally`](https://python-all.ru/2.7/reference/compound_stmts.html#finally).4243#### `imp.new_module(name)`4445Возвращает новый пустой объект модуля с именем *name*. Этот объект *не* вставляется в `sys.modules`.4647#### `imp.lock_held()`4849Возвращает `True`, если блокировка импорта в настоящее время удерживается, иначе `False`. На платформах без поддержки потоков всегда возвращает `False`.5051На платформах с потоками поток, выполняющий импорт, удерживает внутреннюю блокировку до завершения импорта. Эта блокировка не позволяет другим потокам выполнять импорт, пока исходный импорт не завершится, что, в свою очередь, предотвращает ситуацию, когда другие потоки могут увидеть незавершённые объекты модулей, созданные исходным потоком в процессе завершения его импорта (а также импортов, если таковые были, которые были вызваны этим).5253#### `imp.acquire_lock()`5455Захватывает блокировку импорта интерпретатора для текущего потока. Эта блокировка должна использоваться хуками импорта для обеспечения потокобезопасности при импорте модулей.5657После того как поток захватил блокировку импорта, тот же поток может захватить её снова без блокировки; поток должен освобождать её один раз за каждый захват.5859На платформах без потоков эта функция ничего не делает.6061Новое в версии 2.3.6263#### `imp.release_lock()`6465Освобождает блокировку импорта интерпретатора. На платформах без потоков эта функция ничего не делает.6667Новое в версии 2.3.6869Следующие константы целочисленных значений, определённые в этом модуле, используются для обозначения результата поиска [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module).7071#### `imp.PY_SOURCE`7273Модуль найден как исходный файл.7475#### `imp.PY_COMPILED`7677Модуль найден как файл скомпилированного кода.7879#### `imp.C_EXTENSION`8081Модуль найден как динамически загружаемая общая библиотека.8283#### `imp.PKG_DIRECTORY`8485Модуль найден как каталог пакета.8687#### `imp.C_BUILTIN`8889Модуль найден как встроенный модуль.9091#### `imp.PY_FROZEN`9293Модуль был найден как замороженный модуль (см. [`init_frozen()`](https://python-all.ru/2.7/library/imp.html#imp.init_frozen)).9495Следующая константа и функции устарели; их функциональность доступна через [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module) или [`load_module()`](https://python-all.ru/2.7/library/imp.html#imp.load_module). Они сохранены для обратной совместимости:9697#### `imp.SEARCH_ERROR`9899Не используется.100101#### `imp.init_builtin(name)`102103Инициализирует встроенный модуль с именем *name* и возвращает его объект-модуль, а также сохраняет его в `sys.modules`. Если модуль уже был инициализирован, он будет инициализирован *заново*. Повторная инициализация включает копирование `__dict__` встроенного модуля из кэшированного модуля в запись модуля в `sys.modules`. Если встроенного модуля с именем *name* не существует, возвращается `None`.104105#### `imp.init_frozen(name)`106107Инициализирует замороженный модуль с именем *name* и возвращает его объект-модуль. Если модуль уже был инициализирован, он будет инициализирован *заново*. Если замороженного модуля с именем *name* не существует, возвращается `None`. (Замороженные модули – это модули, написанные на Python, чей скомпилированный байт-код встраивается в пользовательскую сборку интерпретатора Python с помощью утилиты **freeze**. См. `Tools/freeze/` для получения дополнительной информации.)108109#### `imp.is_builtin(name)`110111Возвращает `1`, если существует встроенный модуль с именем *name*, который можно инициализировать повторно. Возвращает `-1`, если существует встроенный модуль с именем *name*, который нельзя инициализировать повторно (см. [`init_builtin()`](https://python-all.ru/2.7/library/imp.html#imp.init_builtin)). Возвращает `0`, если встроенного модуля с именем *name* не существует.112113#### `imp.is_frozen(name)`114115Возвращает `True`, если существует замороженный модуль (см. [`init_frozen()`](https://python-all.ru/2.7/library/imp.html#imp.init_frozen)) с именем *name*, или `False`, если такого модуля нет.116117#### `imp.load_compiled(name, pathname[, file])`118119Загружает и инициализирует модуль, реализованный как файл с байт-кодом, и возвращает его объект модуля. Если модуль уже был инициализирован, он будет инициализирован *заново*. Аргумент *name* используется для создания или доступа к объекту модуля. Аргумент *pathname* указывает на файл с байт-кодом. Аргумент *file* – это файл с байт-кодом, открытый для чтения в двоичном режиме с начала. В настоящее время это должен быть реальный файловый объект, а не пользовательский класс, эмулирующий файл.120121#### `imp.load_dynamic(name, pathname[, file])`122123Загружает и инициализирует модуль, реализованный как динамически загружаемая разделяемая библиотека, и возвращает его объект-модуль. Если модуль уже был инициализирован, он будет инициализирован *заново*. Повторная инициализация включает копирование атрибута `__dict__` кэшированного экземпляра модуля в значение, используемое в модуле, кэшированном в `sys.modules`. Аргумент *pathname* должен указывать на разделяемую библиотеку. Аргумент *name* используется для построения имени функции инициализации: вызывается внешняя функция C с именем `initname()` в разделяемой библиотеке. Необязательный аргумент *file* игнорируется. (Примечание: использование разделяемых библиотек сильно зависит от системы, и не все системы поддерживают это.)124125**Особенности реализации CPython:** Внутренние механизмы импорта идентифицируют модули расширения по имени файла, поэтому выполнение `foo = load_dynamic("foo", "mod.so")` и `bar = load_dynamic("bar", "mod.so")` приведёт к тому, что оба foo и bar будут ссылаться на один и тот же модуль, независимо от того, экспортирует ли `mod.so` функцию `initbar`. В системах, поддерживающих символьные ссылки, их можно использовать для импорта нескольких модулей из одной разделяемой библиотеки, так как каждая ссылка на модуль будет использовать другое имя файла.126127#### `imp.load_source(name, pathname[, file])`128129Загружает и инициализирует модуль, реализованный как исходный файл Python, и возвращает его объект-модуль. Если модуль уже был инициализирован, он будет инициализирован *заново*. Аргумент *name* используется для создания или доступа к объекту модуля. Аргумент *pathname* указывает на исходный файл. Аргумент *file* – это исходный файл, открытый для чтения как текст, с начала. В настоящее время это должен быть реальный файловый объект, а не определённый пользователем класс, эмулирующий файл. Обратите внимание, что если существует правильно соответствующий скомпилированный файл (с суффиксом `.pyc` или `.pyo`), он будет использован вместо разбора данного исходного файла.130131#### `class imp.NullImporter(path_string)`132133Тип [`NullImporter`](https://python-all.ru/2.7/library/imp.html#imp.NullImporter) – это хук импорта [**PEP 302**](https://python-all.ru/2.7/library/imp.html), который обрабатывает строки пути, не являющиеся каталогами, и не находит ни одного модуля. Вызов этого типа с существующим каталогом или пустой строкой вызывает [`ImportError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.ImportError). В противном случае возвращается экземпляр [`NullImporter`](https://python-all.ru/2.7/library/imp.html#imp.NullImporter).134135Python добавляет экземпляры этого типа в `sys.path_importer_cache` для любых записей пути, которые не являются каталогами и не обрабатываются никакими другими хуками путей в `sys.path_hooks`. Экземпляры имеют только один метод:136137#### `find_module(fullname[, path])`138139Этот метод всегда возвращает `None`, указывая, что запрошенный модуль не найден.140141Новое в версии 2.5.142143## 31.1.1. Примеры144145Следующая функция эмулирует то, что было стандартным оператором импорта до Python 1.4 (без иерархических имён модулей). (Эта *реализация* не работала бы в той версии, так как [`find_module()`](https://python-all.ru/2.7/library/imp.html#imp.find_module) была расширена, а [`load_module()`](https://python-all.ru/2.7/library/imp.html#imp.load_module) был добавлен в 1.4.)146147```python148import imp149import sys150151def __import__(name, globals=None, locals=None, fromlist=None):152 # Быстрый путь: проверить, импортирован ли модуль ранее.153 try:154 return sys.modules[name]155 except KeyError:156 pass157158 # Если любой из следующих вызовов вызывает исключение,159 # возникает проблема, которую мы не можем обработать – пусть вызывающий код обработает её.160161 fp, pathname, description = imp.find_module(name)162163 try:164 return imp.load_module(name, fp, pathname, description)165 finally:166 # Так как возможен выход через исключение, необходимо явно закрыть fp.167 if fp:168 fp.close()169```170171Более полный пример, реализующий иерархические имена модулей и включающий функцию [`reload()`](https://python-all.ru/2.7/library/functions.html#reload), можно найти в модуле `knee`. Модуль `knee` можно найти в `Demo/imputil/` в дистрибутиве исходного кода Python.172