imputil.md
1> **Источник:** https://python-all.ru/2.7/library/imputil.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 31.3. [`imputil`](https://python-all.ru/2.7/library/imputil.html#module-imputil) – Утилиты импорта89Устарело с версии 2.6: Модуль [`imputil`](https://python-all.ru/2.7/library/imputil.html#module-imputil) удалён в Python 3.1011Этот модуль предоставляет очень удобный и полезный механизм для настраиваемых [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import) хуков. По сравнению со старым модулем `ihooks`, [`imputil`](https://python-all.ru/2.7/library/imputil.html#module-imputil) использует гораздо более простой и прямой подход к настраиваемым функциям [`import`](https://python-all.ru/2.7/reference/simple_stmts.html#import).1213#### `class imputil.ImportManager([fs_imp])`1415Управляет процессом импорта.1617#### `install([namespace])`1819Устанавливает этот ImportManager в указанное пространство имён.2021#### `uninstall()`2223Восстанавливает предыдущий механизм импорта.2425#### `add_suffix(suffix, importFunc)`2627Не документировано.2829#### `class imputil.Importer`3031Базовый класс для замены стандартных функций импорта.3233#### `import_top(name)`3435Импортирует модуль верхнего уровня.3637#### `get_code(parent, modname, fqname)`3839Находит и извлекает код для указанного модуля.4041*parent* указывает родительский модуль для определения контекста импорта. Может быть `None`, что означает отсутствие конкретного контекста поиска.4243*modname* указывает отдельный модуль (не составное имя) внутри родительского.4445*fqname* указывает полное квалифицированное имя модуля. Это (потенциально) составное имя от “корня” пространства имён модулей до modname.4647Если родитель отсутствует, то modname == fqname.4849Этот метод должен возвращать `None` или кортеж из 3 элементов.5051> - Если модуль не найден, следует вернуть `None`.52> - Первый элемент кортежа из 2 или 3 элементов должен быть целым числом 0 или 1, указывающим, является ли найденный модуль пакетом.53> - Второй элемент – это объект кода для модуля (он будет выполнен в пространстве имён нового модуля). Этот элемент также может быть полностью загруженным объектом модуля (например, загруженным из динамической библиотеки).54> - Третий элемент – это словарь пар имя/значение, которые будут вставлены в новый модуль до выполнения объекта кода. Это предусмотрено на случай, если код модуля ожидает определённые значения (например, где был найден модуль). Когда второй элемент является объектом модуля, эти имена/значения будут вставлены *после* загрузки/инициализации модуля.5556#### `class imputil.BuiltinImporter`5758Эмулирует механизм импорта для встроенных и замороженных модулей. Это подкласс класса [`Importer`](https://python-all.ru/2.7/library/imputil.html#imputil.Importer).5960#### `get_code(parent, modname, fqname)`6162Не документировано.6364#### `imputil.py_suffix_importer(filename, finfo, fqname)`6566Не документировано.6768#### `class imputil.DynLoadSuffixImporter([desc])`6970Не документировано.7172#### `import_file(filename, finfo, fqname)`7374Без документации.7576## 31.3.1. Примеры7778Это повторная реализация иерархического импорта модулей.7980Этот код предназначен для чтения, а не для выполнения. Однако он работает – всё, что нужно сделать для его включения, – это «import knee».8182(Название – это игра слов, отсылающая к более громоздкому предшественнику этого модуля – «ni».)8384```python85import sys, imp, __builtin__8687# Замена для __import__()88def import_hook(name, globals=None, locals=None, fromlist=None):89 parent = determine_parent(globals)90 q, tail = find_head_package(parent, name)91 m = load_tail(q, tail)92 if not fromlist:93 return q94 if hasattr(m, "__path__"):95 ensure_fromlist(m, fromlist)96 return m9798def determine_parent(globals):99 if not globals or not globals.has_key("__name__"):100 return None101 pname = globals['__name__']102 if globals.has_key("__path__"):103 parent = sys.modules[pname]104 assert globals is parent.__dict__105 return parent106 if '.' in pname:107 i = pname.rfind('.')108 pname = pname[:i]109 parent = sys.modules[pname]110 assert parent.__name__ == pname111 return parent112 return None113114def find_head_package(parent, name):115 if '.' in name:116 i = name.find('.')117 head = name[:i]118 tail = name[i+1:]119 else:120 head = name121 tail = ""122 if parent:123 qname = "%s.%s" % (parent.__name__, head)124 else:125 qname = head126 q = import_module(head, qname, parent)127 if q: return q, tail128 if parent:129 qname = head130 parent = None131 q = import_module(head, qname, parent)132 if q: return q, tail133 raise ImportError("No module named " + qname)134135def load_tail(q, tail):136 m = q137 while tail:138 i = tail.find('.')139 if i < 0: i = len(tail)140 head, tail = tail[:i], tail[i+1:]141 mname = "%s.%s" % (m.__name__, head)142 m = import_module(head, mname, m)143 if not m:144 raise ImportError("No module named " + mname)145 return m146147def ensure_fromlist(m, fromlist, recursive=0):148 for sub in fromlist:149 if sub == "*":150 if not recursive:151 try:152 all = m.__all__153 except AttributeError:154 pass155 else:156 ensure_fromlist(m, all, 1)157 continue158 if sub != "*" and not hasattr(m, sub):159 subname = "%s.%s" % (m.__name__, sub)160 submod = import_module(sub, subname, m)161 if not submod:162 raise ImportError("No module named " + subname)163164def import_module(partname, fqname, parent):165 try:166 return sys.modules[fqname]167 except KeyError:168 pass169 try:170 fp, pathname, stuff = imp.find_module(partname,171 parent and parent.__path__)172 except ImportError:173 return None174 try:175 m = imp.load_module(fqname, fp, pathname, stuff)176 finally:177 if fp: fp.close()178 if parent:179 setattr(parent, partname, m)180 return m181182# Замена для reload()183def reload_hook(module):184 name = module.__name__185 if '.' not in name:186 return import_module(name, name, None)187 i = name.rfind('.')188 pname = name[:i]189 parent = sys.modules[pname]190 return import_module(name[i+1:], name, parent)191192# Сохранить исходные хуки193original_import = __builtin__.__import__194original_reload = __builtin__.reload195196# Теперь установить наши хуки197__builtin__.__import__ = import_hook198__builtin__.reload = reload_hook199```200201Также см. модуль `importers` (находится в `Demo/imputil/` в дистрибутиве исходного кода Python) для дополнительных примеров.202