2012-03-03 2 views
3

Предположим, что A - это каталог пакетов, B - это модуль внутри каталога, а X - это функция или переменная, написанная на B. Как импортировать X с помощью синтаксиса __import__()? Использование SciPy в качестве примера:от A.B import X используя __import__?

Что я хочу:

from scipy.constants.constants import yotta 

Что не работает:

>>> __import__("yotta", fromlist="scipy.constants.constants") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named yotta 

>>> __import__("yotta", fromlist=["scipy.constants.constants"]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named yotta 

>>> __import__("yotta", fromlist=["scipy","constants","constants"]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named yotta 

>>> __import__("scipy.constants.constants.yotta", fromlist=["scipy.constants.constats"]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No module named yotta 

Любые предложения будут оценены.

ответ

3

Оператор питон импорта выполняет две задачи (курсив мой.): ​​Погрузка модуль и сделать его доступным в пространстве имен.

import foo.bar.baz 

обеспечит имя foo в пространстве имен, не baz, так __import__ даст вам foo

foo = __import__('foo.bar.baz') 

С другой стороны

from foo.bar.baz import a, b 

не делает модуль доступен, но обязательным условием для выполнения заданий является baz. это соответствует

_tmp_baz = __import__('foo.bar.baz', fromlist=['a', 'b']) 
a = _tmp_baz.a 
b = _tmp_baz.b 

без временного видимого, конечно.

функция __import__ не обеспечивает наличие a и b, поэтому, когда вы хотите baz вы можете просто дать что-нибудь в fromlist аргумент поставить __import__ в режиме «от входа».

Таким образом, решение является следующим.Предполагая, что «yotta» задан как строковая переменная, я использовал getattr для доступа к атрибутам.

yotta = getattr(__import__('scipy.constants.constants', 
          fromlist=['yotta']), 
       'yotta') 
+0

Это, наконец, делает то, что мне нужно. Я не могу сказать, что я понимаю, почему оператор импорта не кричит, если элемент fromlist не существует (т. Е. Заменить «yotta» на «yyyy»). Но, по крайней мере, вы получаете атрибут AttributeError, если «yyyy» не существует. Спасибо за помощь! – VioChemist

1
__import__("scipy.constants.constants", fromlist=["yotta"]) 

Аргумент fromlist эквивалентно стороне правой руки из from LHS import RHS.


From the docs:

__import__(name[, globals[, locals[, fromlist[, level]]]])

[...]

fromlist дает имена объектов или подмодулей, которые должны быть импортированы из модулязаданной name.

[...]

С другой стороны, утверждение from spam.ham import eggs, sausage as saus приводит

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1) 
eggs = _temp.eggs 
saus = _temp.sausage 

+0

Хорошо ... тогда я смущен, как какой-либо из моего кода в этом пункте работал. Я использовал эквивалент: dist = __import __ ('scipy.stats.distributions', fromlist = ['scipy', 'stats']) потому что, если я оставлю вне списка, это просто будет ' SciPy. Так ли это работает? – VioChemist

+0

Нет, это не так. Я не уверен, как ваш код мог работать. – Amber

+0

это еще не совсем верно. если я говорю yotta = __import __ (и т. д.), yotta - это просто scipy.constants.constants, и для получения значения вам нужно сделать yotta.yotta – VioChemist

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