Содержание страницы
31.3. imputil – Утилиты импорта¶imputil – Import utilities
Устарело с версии 2.6: Модуль imputil удалён в Python 3.
Этот модуль предоставляет очень удобный и полезный механизм для настраиваемых
import хуков. По сравнению со старым модулем ihooks,
imputil использует гораздо более простой и прямой
подход к настраиваемым функциям import.
-
class
imputil.ImportManager([fs_imp])¶ Управляет процессом импорта.
-
install([namespace])¶ Устанавливает этот ImportManager в указанное пространство имён.
-
uninstall()¶ Восстанавливает предыдущий механизм импорта.
-
add_suffix(suffix, importFunc)¶ Не документировано.
-
-
class
imputil.Importer¶ Базовый класс для замены стандартных функций импорта.
-
import_top(name)¶ Импортирует модуль верхнего уровня.
-
get_code(parent, modname, fqname)¶ Находит и извлекает код для указанного модуля.
parent указывает родительский модуль для определения контекста импорта. Может быть
None, что означает отсутствие конкретного контекста поиска.modname указывает отдельный модуль (не составное имя) внутри родительского.
fqname указывает полное квалифицированное имя модуля. Это (потенциально) составное имя от “корня” пространства имён модулей до modname.
Если родитель отсутствует, то modname == fqname.
Этот метод должен возвращать
Noneили кортеж из 3 элементов.Если модуль не найден, следует вернуть
None.Первый элемент кортежа из 2 или 3 элементов должен быть целым числом 0 или 1, указывающим, является ли найденный модуль пакетом.
Второй элемент – это объект кода для модуля (он будет выполнен в пространстве имён нового модуля). Этот элемент также может быть полностью загруженным объектом модуля (например, загруженным из динамической библиотеки).
Третий элемент – это словарь пар имя/значение, которые будут вставлены в новый модуль до выполнения объекта кода. Это предусмотрено на случай, если код модуля ожидает определённые значения (например, где был найден модуль). Когда второй элемент является объектом модуля, эти имена/значения будут вставлены после загрузки/инициализации модуля.
-
-
class
imputil.BuiltinImporter¶ Эмулирует механизм импорта для встроенных и замороженных модулей. Это подкласс класса
Importer.-
get_code(parent, modname, fqname)¶ Не документировано.
-
-
imputil.py_suffix_importer(filename, finfo, fqname)¶ Не документировано.
-
class
imputil.DynLoadSuffixImporter([desc])¶ Не документировано.
-
import_file(filename, finfo, fqname)¶ Без документации.
-
31.3.1. Примеры¶Examples
Это повторная реализация иерархического импорта модулей.
Этот код предназначен для чтения, а не для выполнения. Однако он работает – всё, что нужно сделать для его включения, – это «import knee».
(Название – это игра слов, отсылающая к более громоздкому предшественнику этого модуля – «ni».)
import sys, imp, __builtin__
# Замена для __import__()
def import_hook(name, globals=None, locals=None, fromlist=None):
parent = determine_parent(globals)
q, tail = find_head_package(parent, name)
m = load_tail(q, tail)
if not fromlist:
return q
if hasattr(m, "__path__"):
ensure_fromlist(m, fromlist)
return m
def determine_parent(globals):
if not globals or not globals.has_key("__name__"):
return None
pname = globals['__name__']
if globals.has_key("__path__"):
parent = sys.modules[pname]
assert globals is parent.__dict__
return parent
if '.' in pname:
i = pname.rfind('.')
pname = pname[:i]
parent = sys.modules[pname]
assert parent.__name__ == pname
return parent
return None
def find_head_package(parent, name):
if '.' in name:
i = name.find('.')
head = name[:i]
tail = name[i+1:]
else:
head = name
tail = ""
if parent:
qname = "%s.%s" % (parent.__name__, head)
else:
qname = head
q = import_module(head, qname, parent)
if q: return q, tail
if parent:
qname = head
parent = None
q = import_module(head, qname, parent)
if q: return q, tail
raise ImportError("No module named " + qname)
def load_tail(q, tail):
m = q
while tail:
i = tail.find('.')
if i < 0: i = len(tail)
head, tail = tail[:i], tail[i+1:]
mname = "%s.%s" % (m.__name__, head)
m = import_module(head, mname, m)
if not m:
raise ImportError("No module named " + mname)
return m
def ensure_fromlist(m, fromlist, recursive=0):
for sub in fromlist:
if sub == "*":
if not recursive:
try:
all = m.__all__
except AttributeError:
pass
else:
ensure_fromlist(m, all, 1)
continue
if sub != "*" and not hasattr(m, sub):
subname = "%s.%s" % (m.__name__, sub)
submod = import_module(sub, subname, m)
if not submod:
raise ImportError("No module named " + subname)
def import_module(partname, fqname, parent):
try:
return sys.modules[fqname]
except KeyError:
pass
try:
fp, pathname, stuff = imp.find_module(partname,
parent and parent.__path__)
except ImportError:
return None
try:
m = imp.load_module(fqname, fp, pathname, stuff)
finally:
if fp: fp.close()
if parent:
setattr(parent, partname, m)
return m
# Замена для reload()
def reload_hook(module):
name = module.__name__
if '.' not in name:
return import_module(name, name, None)
i = name.rfind('.')
pname = name[:i]
parent = sys.modules[pname]
return import_module(name[i+1:], name, parent)
# Сохранить исходные хуки
original_import = __builtin__.__import__
original_reload = __builtin__.reload
# Теперь установить наши хуки
__builtin__.__import__ = import_hook
__builtin__.reload = reload_hook
Также см. модуль importers (находится
в Demo/imputil/ в дистрибутиве исходного кода Python) для дополнительных примеров.