2008-09-29 6 views
16

Учитывая строку с именем модуля, как импортировать все в модуле, как если бы вы называли:Как сделать эквивалент «import * from module» с помощью функции __import__ Python?

from module import * 

т.е. заданная строка S = «модуль», как же получить эквивалент следующее:

__import__(S, fromlist="*") 

Это не похоже на ожидаемое (так как оно ничего не импортирует).

ответ

30

Пожалуйста, передумайте. Единственное, что хуже import * - magicimport *.

Если вы действительно хотите:

m = __import__ (S) 
try: 
    attrlist = m.__all__ 
except AttributeError: 
    attrlist = dir (m) 
for attr in attrlist: 
    globals()[attr] = getattr (m, attr) 
+0

может быть лучше: для ATTR в м .__ all__ ? – 2008-09-29 04:47:34

+0

@Sergei: нет гарантии, что модули определит __all__ – 2008-09-29 04:55:13

+1

@ Джон Милликин: Но если модуль определяет __all__, вы должны его заметить – 2008-09-29 06:56:50

0

Основная проблема заключается в том, что я занимаюсь разработкой некоторые Django, но на более чем одного хоста (с коллегами), все с разными настройками. Я надеялся, что сделать что-то подобное в проекте/settings.py файл:

from platform import node 

settings_files = { 'BMH.lan': 'settings_bmh.py", ... } 

__import__(settings_files[ node() ]) 

казался простым решением (при этом элегантный), но я согласен, что он имеет запах к нему и простота выходит цикл, когда вы должны использовать логику, как то, что написал Джон Милликин (спасибо). Вот, по существу, решение, с которым я столкнулся:

from platform import node 

from settings_global import * 

n = node() 

if n == 'BMH.lan': 
    from settings_bmh import * 
# add your own, here... 
else: 
    raise Exception("No host settings for '%s'. See settings.py." % node()) 

Что подходит для наших целей.

-2

я не нашел хороший способ сделать это, так что я взял простой, но некрасивый путь от http://www.djangosnippets.org/snippets/600/

try: 
    import socket 
    hostname = socket.gethostname().replace('.','_') 
    exec "from host_settings.%s import *" % hostname 
except ImportError, e: 
    raise e 
1

Похоже, что вы можете также использовать dict.update() на словарях модуля в ваш случай:

config = [__import__(name) for name in names_list] 

options = {} 
for conf in config: 
    options.update(conf.__dict__) 

Update: Я думаю, что есть короткий «функциональный» версия этого:

options = reduce(dict.update, map(__import__, names_list)) 
5

Вот мое решение для динамического именования файлов локальных настроек для Django. Обратите внимание на приведенное ниже дополнение проверки, чтобы не включать атрибуты, содержащие «__» из импортированного файла. Глобальный номер __name__ был перезаписан с именем модуля локального файла настроек, что вызвало проблемы setup_environ(), используемые в файле управления.py.

try: 
    import socket 
    HOSTNAME = socket.gethostname().replace('.','_') 
    # See http://docs.python.org/library/functions.html#__import__ 
    m = __import__(name="settings_%s" % HOSTNAME, globals=globals(), locals=locals(), fromlist="*") 
    try: 
     attrlist = m.__all__ 
    except AttributeError: 
     attrlist = dir(m)   
    for attr in [a for a in attrlist if '__' not in a]: 
     globals()[attr] = getattr(m, attr) 

except ImportError, e: 
    sys.stderr.write('Unable to read settings_%s.py\n' % HOSTNAME) 
    sys.exit(1) 

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

  • Нет связанных вопросов^_^