AttributeError: объект 'module' не имеет атрибута
У меня есть два модуля python:
a.py
import b
def hello():
print "hello"
print "a.py"
print hello()
print b.hi()
b.py
import a
def hi():
print "hi"
Когда я запускаю a.py
, я получаю:
AttributeError: 'module' object has no attribute 'hi'
Что означает ошибка? Как это исправить?
Ответы
Ответ 1
У вас есть взаимный импорт верхнего уровня, который почти всегда плохая идея.
Если у вас действительно есть взаимный импорт в 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
, но на самом деле импортная работа выполняется только в первый раз. Второй и последующий раз импортировать модуль, это быстрая операция.)
Ответ 2
Я также видел эту ошибку, когда непреднамеренно назвал модуль с тем же именем, что и один из стандартных модулей Python. Например. У меня был модуль под названием commands
, который также является библиотечным модулем Python. Это оказалось трудно отследить, так как он корректно работал в моей локальной среде разработки, но с ошибкой при работе в Google App Engine не удался.
Ответ 3
Проблема заключается в круговой зависимости между модулями. a
импортирует b
и b
импортирует a
. Но сначала нужно загрузить одну из них - в этом случае python заканчивает инициализацию модуля a
до b
и b.hi()
еще не существует, когда вы пытаетесь получить к нему доступ в a
.
Ответ 4
Я получил эту ошибку, ссылаясь на перечисление, которое было импортировано неправильно, например:
from package import MyEnumClass
# ...
# in some method:
return MyEnumClass.Member
Правильный импорт:
from package.MyEnumClass import MyEnumClass
Надеюсь, что кто-то поможет
Ответ 5
Я испытал эту ошибку, потому что модуль фактически не импортировался. Код выглядел так:
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
.
Ответ 6
Я столкнулся с этой проблемой, когда проверил более старую версию репозитория из git. Git заменил мои .py
файлы, но оставил неотслеживаемыми .pyc
файлы. Поскольку файлы .py
и .pyc
не синхронизированы, команда import
в файле .py
не смогла найти соответствующий модуль в файлах .pyc
.
Решением было просто удалить файлы .pyc
и позволить им автоматически восстанавливаться.
Ответ 7
Все вышеприведенные ответы великолепны, но я бы хотел здесь побеседовать. Если вы не обнаружили проблем, упомянутых выше, попробуйте очистить вашу рабочую среду. Это сработало для меня.
Ответ 8
Не уверен, как, но приведенные ниже изменения отсортировали мою проблему:
у меня было имя файла и имя импорта, например, у меня было имя файла как emoji.py, и я пытался импортировать эмодзи. Но изменение имени файла решило проблему.
Надеюсь, это поможет
Ответ 9
Круговой импорт вызывает проблемы, но в Python есть способы его уменьшения.
Проблема в том, что когда вы запускаете python a.py
, он запускает a.py
но не помечает его как импортированный как модуль. Так что в свою очередь a.py
→ модуль импорта b → модуль импорта a → модуль импорта b. Последний импортирует no-op, так как b в настоящее время импортируется, и Python защищает от этого. И b пока пустой модуль. Поэтому, когда он выполняет b.hi()
, он не может ничего найти.
Обратите внимание, что b.hi()
который был выполнен, находится во время a.py
→ module b → module a, а не в a.py
напрямую.
В вашем конкретном примере вы можете просто запустить python -c 'import a'
на верхнем уровне, поэтому первое выполнение a.py
регистрируется как импорт модуля.
Ответ 10
Я столкнулся с той же проблемой. исправлено с помощью reload
.
import the_module_name
from importlib import reload
reload(the_module_name)
Ответ 11
@MD5 То же самое для меня, попробуйте изменить имя модуля или импортировать функцию напрямую