Переопределить пространство имен в 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, как он его нашел.