从脚本导入已安装的软件包会引发“AttributeError:module has no attribute”或“ImportError:无法导入名称”

时间:2016-03-27 17:27:05

标签: python exception python-module shadowing

我有一个名为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

3 个答案:

答案 0 :(得分:44)

这是因为名为requests.py的本地模块会影响您尝试使用的已安装requests模块。当前目录前置于sys.path,因此本地名称优先于已安装的名称。

出现这个问题时,额外的调试技巧是仔细查看Traceback,并意识到您所讨论的脚本名称与您尝试导入的模块匹配:

注意您在脚本中使用的名称:

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

您要导入的模块:requests

将模块重命名为其他名称以避免名称冲突。

Python可能会在requests.pyc文件旁边生成requests.py文件(在Python 3的__pycache__目录中)。在重命名后删除它,因为解释器仍将引用该文件,重新生成错误。但是,如果pyc文件已被删除,则__pycache__ 中的py文件应不会影响您的代码。

在示例中,将文件重命名为my_requests.py,删除requests.pyc,然后再次成功运行会打印<Response [200]>

答案 1 :(得分:6)

对于原始问题的作者,以及对于那些在“ AttributeError:模块没有属性”字符串上进行搜索的人,则根据已接受的答案的常见解释是,用户创建的脚本具有名称冲突带有库文件名。但是请注意,问题可能不在于生成错误的脚本名称(与上述情况相同),也不在于该脚本显式导入的库模块的名称。要弄清楚是哪个文件引起了问题,可能需要做一些侦探工作。

以一个说明问题的示例为例,假设您正在创建一个脚本,该脚本使用“十进制”库使用十进制数字进行精确的浮点计算,并将您的脚本命名为“ mydecimal.py”,其中包含行“ import decimal”。没问题,但是您发现它会引发此错误:

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

如果您以前 编写了一个名为“ numbers.py”的脚本,则会发生这种情况,因为“十进制”库调用标准库“ numbers”,但找到了旧脚本。即使您删除了它,也可能不会解决问题,因为python可能已将其转换为字节码并将其存储为“ numbers.pyc”在缓存中,因此您也必须对其进行追踪。 >

答案 2 :(得分:0)

Python正在requests.py模块内寻找请求对象。

重命名该文件至其他文件或使用

from __future__ import absolute_import 

位于requests.py模块的顶部。