Ошибка атрибута:Объект «модуль» не имеет атрибута
-
12-09-2019 - |
Вопрос
У меня есть два модуля Python:
а.py
import b
def hello():
print "hello"
print "a.py"
print hello()
print b.hi()
б.пи
import a
def hi():
print "hi"
Когда я бегу a.py
, Я получил:
AttributeError: 'module' object has no attribute 'hi'
Что означает ошибка?Как это исправить?
Решение
У вас есть взаимный импорт верхнего уровня, что почти всегда является плохой идеей.
Если вам действительно необходим взаимный импорт в Python, способ сделать это — импортировать их внутри функции:
# In b.py:
def cause_a_to_do_something():
import a
a.do_something()
Теперь a.py может безопасно делать import b
не вызывая проблем.
(На первый взгляд может показаться, что cause_a_to_do_something()
было бы чрезвычайно неэффективно, потому что это делает import
каждый раз, когда вы его вызываете, но на самом деле работа по импорту выполняется только в первый раз.Второй и последующие импорты модуля выполняются быстро.)
Другие советы
Я также видел эту ошибку, когда случайно назвал модуль тем же именем, что и один из стандартных модулей Python.Например.У меня был модуль под названием commands
который также является библиотечным модулем Python.Это оказалось сложно отследить, поскольку в моей локальной среде разработки оно работало правильно, но при запуске в Google App Engine произошел сбой с указанной ошибкой.
Проблема в циклической зависимости между модулями. a
импорт b
и b
импорт a
.Но сначала необходимо загрузить один из них — в этом случае Python инициализирует модуль. a
до b
и b.hi()
еще не существует, когда вы пытаетесь получить к нему доступ в a
.
Я получил эту ошибку, ссылаясь на перечисление, которое было импортировано неправильно, например:
from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member
Правильный импорт:
from package.MyEnumClass import MyEnumClass
Надеюсь, это поможет кому-то
Я столкнулся с этой ошибкой, поскольку модуль фактически не был импортирован.Код выглядел так:
import a.b, a.c
# ...
something(a.b)
something(a.c)
something(a.d) # My addition, which failed.
Последняя строка привела к AttributeError
.Причина была в том, что я не заметил, что субмодули a
(a.b
и a.c
) были явно импортированы и предположили, что import
заявление фактически импортировано a
.
Все приведенные выше ответы великолепны, но я хотел бы присоединиться и здесь.Если вы не заметили никакой проблемы, упомянутой выше, попробуйте очистить рабочую среду.Это сработало для меня.
Я столкнулся с этой проблемой, когда проверял старую версию репозитория из git.Git заменил мой .py
файлы, но оставил неотслеживаемым .pyc
файлы.Поскольку .py
файлы и .pyc
файлы были не синхронизированы, import
командовать в .py
файл не смог найти соответствующий модуль в .pyc
файлы.
Решением было просто удалить .pyc
файлы и позволить им автоматически восстанавливаться.
Я столкнулся с той же проблемой.исправлено с помощью reload
.
import the_module_name
from importlib import reload
reload(the_module_name)
Не знаю, как, но изменение ниже решило мою проблему:
у меня было одинаковое имя файла и имя импорта, например, у меня было имя файла как emoji.py, и я пытался импортировать смайлики.Но изменение имени файла решило проблему.
Надеюсь, что это поможет
Циклический импорт вызывает проблемы, но в Python есть встроенные способы их решения.
Проблема в том, что когда вы запускаете python a.py
, он работает a.py
но не отмечать его как импортированный как модуль.Итак, в свою очередь a.py
-> импортирует модуль b -> импортирует модуль a -> импортирует модуль b.Последний импорт не выполняется, поскольку в настоящее время импортируется b, и Python защищает от этого.И b на данный момент является пустым модулем.Поэтому, когда он выполняется b.hi()
, он ничего не может найти.
Обратите внимание, что b.hi()
что было казнено во время a.py
-> модуль b -> модуль a, не в a.py
напрямую.
В вашем конкретном примере вы можете просто запустить python -c 'import a'
на верхнем уровне, поэтому первое выполнение a.py
регистрируется как импортирующий модуль.
@MD5 То же самое и для меня. Попробуйте изменить имя модуля или импортировать функцию напрямую.
на убунту 18.04 ( виртуальное окружение, python.3.6.x), следующее перезагрузить фрагмент решено проблема для меня:
main.py
import my_module # my_modyle.py
from importlib import reload # reload
reload(my_module)
print(my_module)
print(my_modeule.hello())
где:
|--main.py
|--my_module.py
для большего документация проверять : здесь