从脚本中导入已安装的包会产生 "AttributeError:module has no attribute "或 "ImportError:cannot import name "的错误。

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




Answer 1 idjaw


发生这种情况是因为您的本地模块名为 requests.py 遮盖了您尝试使用的已安装 requests 模块。当前目录位于 sys.path 之前,因此本地名称优先于已安装名称。

当出现这种情况时,一个额外的调试提示是仔细观察Traceback,并意识到你的脚本名称与你要导入的模块相匹配。

注意你的脚本中使用的名字。

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

您尝试导入的模块: requests

将你的模块重命名为其他的东西,以避免名称冲突。

蟒蛇可能产生 requests.pyc 文件旁边的 requests.py 文件(在 __pycache__ 在Python 3目录)。重命名后也要删除该文件,因为解释器仍将引用该文件,从而重新产生错误。然而, pyc 文件 __pycache__ 应该,如果不影响你的代码 py 文件已被删除。

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




Answer 2 Dave Rove


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

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

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

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