Переопределить пространство имен в Python
Скажем, что есть папка '/home/user/temp/a40bd22344'. Имя полностью случайное и изменяется на каждой итерации. Мне нужно иметь возможность импортировать эту папку в Python с использованием фиксированного имени, например "project". Я знаю, что могу добавить эту папку в sys.path, чтобы включить импортный поиск, но есть ли способ заменить "a40bd22344" на "проект"?
Возможно, некоторые умные хаки в init.py?
Добавлено:
Он должен быть глобальным - то есть, другие скрипты загружают "проект" по стандарту:
import project
Соблюдайте правильную работу, загрузив вместо этого a40bd22344.
Ответы
Ответ 1
Сначала импортируйте его с помощью import:
>>> __import__('temp/a40bd22344')
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>
Затем вы убедитесь, что этот модуль известен Python как project
:
>>> import sys
>>> sys.modules['project'] = sys.modules.pop('temp/a40bd22344')
После этого любой импортирующий проект в текущем сеансе Python получит исходный модуль
>>> import project
>>> project
<module 'temp/a40bd22344' from 'temp/a40bd22344/__init__.py'>
Это будет работать и для подмодулей: если у вас есть foobar.py в том же месте, вы получите
>>> import project.foobar
>>> project.foobar
<module 'project.foobar' from 'temp/a40bd22344/foobar.py'>
Добавление. Здесь я запускаю:
>>> print sys.version
2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)]
Ответ 2
Здесь один из способов сделать это, не касаясь sys.path, используя модуль imp
в Python:
import imp
f, filename, desc = imp.find_module('a40bd22344', ['/home/user/temp/'])
project = imp.load_module('a40bd22344', f, filename, desc)
project.some_func()
Вот ссылка на хорошую документацию по модулю imp
:
Ответ 3
Конечно, project = __import__('a40bd22344')
после того, как sys.path
будет установлен правильно, будет просто работать.
Предположим, вы хотите сделать это в функции, использующей полный путь в качестве аргумента и правильно настроив глобальный импорт project
(а также после магического создания import project
в других модулях). Кусок торта:
def weirdimport(fullpath):
global project
import os
import sys
sys.path.append(os.path.dirname(fullpath))
try:
project = __import__(os.path.basename(fullpath))
sys.modules['project'] = project
finally:
del sys.path[-1]
это также оставляет sys.path, как он его нашел.