Я получаю сообщение об ошибке «объект модуля не имеет атрибута ...» при попытке использовать созданную мной иерархию пакетов . Ошибка напоминает ошибку, которую вы получаете при циклическом импорте (т.е. модуль 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
Модуль charlie импортирует эхо, которое, в свою очередь, импортирует дельту. Если alpha / bravo / __ init__.py (например, alpha / __ init__.py) по существу пусто, сценарий может:
import alpha.bravo.charlie
Проблема возникает, если я пытаюсь импортировать alpha.bravo.charlie в alpha / bravo / __ init__.py (думая, что я мог бы найти там соответствующие классы / методы, и сценарий подойдет ' import alpha.bravo ').
Код:
alpha / __ init __. Py
(blank)
alpha / bravo / __ init __. Py
import alpha.bravo.charlie
alpha / bravo / charlie.py
import alpha.bravo.echo
def charlie_foo(x): return str(x)
def charlie_bar(x): return alpha.bravo.echo.echo_biz()
alpha / bravo / delta.py
def delta_foo(x): return str(x)
alpha / bravo / 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
Я смог работать вокруг проблемы, но я все же хотел бы понять это. Спасибо.