2009-07-08 3 views
13

Скажите, что есть папка '/ home/user/temp/a40bd22344'. Имя полностью случайное и изменяется на каждой итерации. Мне нужно иметь возможность импортировать эту папку в Python с использованием фиксированного имени, например «project». Я знаю, что могу добавить эту папку в sys.path, чтобы включить импортный поиск, но есть ли способ заменить «a40bd22344» на «проект»?Переопределить пространство имен в Python

Возможно, некоторые умные хаки в init .py?

Добавлено:

Он должен быть глобальным - то есть, другие сценарии загрузки 'проект' через стандарт:

import project 

должны работать должным образом, загружая a40bd22344 вместо этого.

+1

Почему вы не можете исправить процесс создания временного файла? Было бы проще исправить это в источнике, вместо того чтобы создавать сложную работу. Что случилось с исправлением имени в/temp /, чтобы быть настоящим именем модуля? –

+1

Это вне моего контроля, папки создаются сервером CI. – Art

ответ

19

Вы первый импорт его с импорт:

>>> __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'> 

Addendum. Вот что я делаю:

>>> print sys.version 
2.5.2 (r252:60911, Jul 31 2008, 17:28:52) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] 
+0

Отлично, вот что мне нужно, спасибо! – Art

+1

Отлично, за исключением небольших деталей, которые он не работает: в Python 2.6 и 3.1 говорится: «ImportError: Import by filename не поддерживается». В 2.5 просто «ImportError: No module temp/a40bd22344», на __import__ (просто попробовал все три на моем Mac, чтобы подтвердить, что не забыл, как работает __import__!). Я предполагаю, что это работает на вашей платформе, krawyoti и yours, Art, или вы бы не отметили ее как принятую, поэтому мне любопытно: какие платформы это? –

+0

Ну, понятно, что эта лазейка в __import__, которую я использовал, была исправлена. Мне лениво не попробовать в Python 2.6 тоже. – krawyoti

17

Уверенный, 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, как он его нашел.

+0

Я только что добавил разъяснение к моему вопросу, будет ли оно работать и в этом случае? – Art

+1

Alex, поставьте инструкцию __import__ в скобке try..finally, чтобы гарантировать, что sys.path всегда правильно восстановлен. – krawyoti

+1

@Art, поскольку @krawyoti говорит, что это достигается путем вставки его в sys.modules [project], как говорит @krawyoti. @krawyoti, хороший совет - позвольте мне изменить, чтобы отразить эти два изменения. –

24

Вот один из способов сделать это, не касаясь 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 модуле:

+1

Это не касается sys.path, но я думаю, что использование imp заставляет пакет перезагружаться каждый раз, когда этот код выполняется. Я бы предпочел решение Алекса, потому что он поступает правильно, даже если он выполняется несколько раз. –

Смежные вопросы