Почему эти два импорта Python работают по-разному? - PullRequest
7 голосов
/ 18 июля 2011

Предположим следующую структуру кода:

#### 1/hhh/__init__.py: empty

#### 1/hhh/foo/__init__.py:
from hhh.foo.baz import *

#### 1/hhh/foo/bar.py:
xyzzy = 4

#### 1/hhh/foo/baz.py:
import hhh.foo.bar as bar
qux = bar.xyzzy + 10

Я запускаю python внутри 1/ и делаю import hhh.foo.baz. Не удается:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "hhh/foo/__init__.py", line 1, in <module>
    from hhh.foo.baz import *
  File "hhh/foo/baz.py", line 1, in <module>
    import hhh.foo.bar as bar
AttributeError: 'module' object has no attribute 'foo'

Теперь я заменяю baz.py на:

# 1/hhh/foo/baz.py:
from hhh.foo.bar import xyzzy
qux = xyzzy + 10

и снова сделайте import hhh.foo.baz. Теперь он работает, хотя я загружаю тот же модуль, но привязываю только другое имя.

Значит ли это, что различие между import module и from module import name выходит за рамки просто идентификаторов? Что именно здесь происходит?

(Я знаю, что могу использовать относительный импорт, чтобы обойти все это, но все же я хотел бы понять механику. Плюс мне не нравится относительный импорт, как и PEP 8.)

Ответы [ 3 ]

8 голосов
/ 18 июля 2011

Когда вы пишете from hhh.foo.bar import xyzzy интерпретатор Python попытается загрузить xyzzy из модуля hhh.foo.bar. Но если вы напишите import hhh.foo.bar as bar, он сначала попытается найти bar в hhh.foo модуле. Таким образом, он оценивает hhh.foo, делая from hhh.foo.baz import * . hhh.foo.baz пытается оценить hhh.foo, hhh.foo пытается оценить hhh.foo.baz, циклический импорт, исключение.

0 голосов
/ 20 апреля 2012

Почему вы импортируете из hhh.foo.bar в hhh.foo? import bar должно хватить там.

0 голосов
/ 18 июля 2011

in 1/hhh/foo/__init__.py вам нужно установить список __all__ с именами того, что вы хотите экспортировать.т.е. __all__ = ["xyzzy"]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...