Я получаю сообщение об ошибке «объект модуля не имеет атрибута ...» при попытке использовать созданную мной иерархию пакетов. Эта ошибка напоминает ошибку, которую вы получаете при циклическом импорте (т. Е. Модуль a импортирует b и модуль b импортирует a), но я не вижу этой проблемы здесь. Я просмотрел много постов с похожей ошибкой, но ни одно из объяснений, которые я счел вполне подходящим.
Это было замечено в python 2.7.1 и python 2.4.3.
Я поливал его до следующего примера:
Рассмотрим следующую иерархию (см. Код ниже):
alpha
alpha/__init__.py
alpha/bravo
alpha/bravo/__init__.py
alpha/bravo/charlie.py
alpha/bravo/delta.py
alpha/bravo/echo.py
Модуль Чарли импортирует эхо, которое, в свою очередь, импортирует дельту. Если alpha / bravo / __ init__.py (как и alpha / __ init__.py) по существу пустые, скрипт может выполнить:
import alpha.bravo.charlie
Проблема появляется, если я пытаюсь импортировать alpha.bravo.charlie в alpha / bravo / __ init__.py (с мыслью, что я могу вспомнить соответствующие классы / методы там, и скрипт выполнит «import alpha.bravo»).
Код:
альфа / __ __ INIT. Ру
(blank)
альфа / браво / __ __ INIT. Ру
import alpha.bravo.charlie
альфа / браво / charlie.py
import alpha.bravo.echo
def charlie_foo(x): return str(x)
def charlie_bar(x): return alpha.bravo.echo.echo_biz()
альфа / браво / delta.py
def delta_foo(x): return str(x)
альфа / браво / echo.py
import alpha.bravo.delta
print alpha.bravo.delta.delta_foo(1)
def echo_biz(): return 'blah'
Если я попытаюсь:
python -c 'import alpha.bravo'
Я получаю:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/kmkc980/svn/working/azcif/python/lib/alpha/bravo/__init__.py", line 1, in <module>
import alpha.bravo.charlie
File "/home/kmkc980/svn/working/azcif/python/lib/alpha/bravo/charlie.py", line 1, in <module>
import alpha.bravo.echo
File "/home/kmkc980/svn/working/azcif/python/lib/alpha/bravo/echo.py", line 2, in <module>
print alpha.bravo.delta.delta_foo(1)
AttributeError: 'module' object has no attribute 'bravo'
Но если я закомментирую строку импорта в alpha / bravo / __ init__.py, то все будет в порядке:
python -c 'import alpha.bravo'
python -c 'import alpha.bravo.charlie'
1
Более того, если я использую тот же код выше (включая строку импорта в alpha / bravo / __ init__.py), но редактирую все, чтобы исключить уровень 'alpha' иерархии, похоже, он работает нормально.
Итак, иерархия теперь просто:
bravo
bravo/__init__.py
bravo/charlie.py
bravo/delta.py
bravo/echo.py
и я изменяю все строки с "alpha.bravo. *" На "bravo. *"
Тогда без проблем:
python -c 'import bravo'
1
Мне удалось обойти эту проблему, но я все еще хотел бы ее понять. Спасибо.