Подтвердить что ты не робот

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'

Что означает ошибка? Как это исправить?

4b9b3361

Ответ 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 То же самое для меня, попробуйте изменить имя модуля или импортировать функцию напрямую