Я получаю ошибку "объект модуля не имеет атрибута..." при попытке использовать созданную мной иерархию пакетов. Ошибка является напоминанием об ошибке, которую вы получаете, когда имеется циклический импорт (т.е. модуль импорта 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
Модуль charlie импортирует эхо, которое в свою очередь импортирует delta. Если альфа /bravo/ __ init__.py(например, alpha/__ init__.py) по существу пуста, script может выполнять:
import alpha.bravo.charlie
Проблема возникает, если я пытаюсь импортировать alpha.bravo.charlie в alpha/bravo/__ init__.py(с мышлением я мог бы нарисовать соответствующие классы/методы там, а script будет делать "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), но отредактируйте все, чтобы исключить уровень "альфа" иерархии, он работает нормально.
Итак, иерархия теперь просто:
bravo
bravo/__init__.py
bravo/charlie.py
bravo/delta.py
bravo/echo.py
и я меняю все строки на "alpha.bravo. *" на "bravo. *"
Тогда не проблема:
python -c 'import bravo'
1
Мне удалось решить проблему, но я все равно хотел бы ее понять. Спасибо.