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

Импорт установленного пакета из script вызывает "AttributeError: модуль не имеет атрибута" или "ImportError: невозможно импортировать имя"

У меня есть скрипт с именем requests.py, который импортирует пакет запросов. Сценарий либо не может получить доступ к атрибутам из пакета, либо не может импортировать их. Почему это не работает и как я могу это исправить?

Следующий код вызывает AttributeError.

import requests

res = requests.get('http://www.google.ca')
print(res)
Traceback (most recent call last):
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    import requests
  File "/Users/me/dev/rough/requests.py", line 3, in <module>
    requests.get('http://www.google.ca')
AttributeError: module 'requests' has no attribute 'get'

Следующий код вызывает ImportError.

from requests import get

res = get('http://www.google.ca')
print(res)
Traceback (most recent call last):
  File "requests.py", line 1, in <module>
    from requests import get
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    from requests import get
ImportError: cannot import name 'get'

Или код, который импортируется из модуля внутри пакета requests:

from requests.auth import AuthBase
Traceback (most recent call last):
  File "requests.py", line 1, in <module>
    from requests.auth import AuthBase
  File "/Users/me/dev/rough/requests.py", line 1, in <module>
    from requests.auth import AuthBase
ImportError: No module named 'requests.auth'; 'requests' is not a package
4b9b3361

Ответ 1

Это происходит потому, что ваш локальный модуль с именем requests.py затеняет установленный модуль requests, который вы пытаетесь использовать. Текущая директория добавляется к sys.path, поэтому локальное имя имеет приоритет над установленным именем.

Дополнительный отзыв для отладки, когда он появляется, - это внимательно изучить Traceback и понять, что имя вашего script соответствует вашему модулю, который вы пытаетесь импортировать:

Обратите внимание на имя, которое вы использовали в script:

File "/Users/me/dev/rough/requests.py", line 1, in <module>

Модуль, который вы пытаетесь импортировать: requests

Переименуйте свой модуль в другое, чтобы избежать столкновения имен.

Python может сгенерировать файл requests.pyc рядом с вашим файлом requests.py (в каталоге __pycache__ в Python 3). Удалите это также после переименования, поскольку интерпретатор все равно будет ссылаться на этот файл, повторно создавая ошибку. Однако файл pyc в __pycache__ не должен влиять на ваш код, если файл py удален.

В этом примере переименование файла на my_requests.py, удаление requests.pyc и повторное выполнение успешно завершает печать <Response [200]>.

Ответ 2

Для автора исходного вопроса и для тех, кто ищет в строке "AttributeError: модуль не имеет атрибута", общее объяснение согласно принятому ответу состоит в том, что созданный пользователем сценарий имеет конфликт имен с библиотекой. имя файла. Однако обратите внимание, что проблема может заключаться не в имени скрипта, который генерирует ошибку (как это было в предыдущем случае), ни в каком-либо из имен библиотечных модулей, явно импортированных этим скриптом. Может потребоваться небольшая детективная работа, чтобы выяснить, какой файл вызывает проблему.

В качестве примера для иллюстрации проблемы представьте, что вы создаете сценарий, который использует библиотеку "десятичная дробь" для точных вычислений с плавающей запятой с десятичными числами, и вы называете свой сценарий "mydecimal.py", который содержит строку "import decimal ". Никаких проблем с этим нет, но вы обнаружите, что возникает эта ошибка:

AttributeError: 'module' object has no attribute 'Number'

Это произойдет, если вы ранее написали скрипт с именем "numbers.py", потому что "десятичная" библиотека вызывает стандартную библиотеку "числа", но вместо этого находит ваш старый скрипт. Даже если вы удалили это, это может не решить проблему, потому что python мог бы преобразовать это в байт-код и сохранить его в кеше как "numbers.pyc", так что вам также придется выследить это.