从脚本导入已安装的包会引发“AttributeError:模块没有属性”或“ImportError:无法导入名称”

Posted

技术标签:

【中文标题】从脚本导入已安装的包会引发“AttributeError:模块没有属性”或“ImportError:无法导入名称”【英文标题】:Importing installed package from script raises "AttributeError: module has no attribute" or "ImportError: cannot import name" 【发布时间】:2016-07-15 00:06:48 【问题描述】:

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

【问题讨论】:

请注意,这是对一个常见问题的规范回答……除非您确定其他问题有更好、更完整的答案,否则请勿重复关闭。跨度> 【参考方案1】:

Python 正在您的 requests.py 模块中寻找 requests 对象。

将该文件重命名到其他文件或使用

from __future__ import absolute_import 

requests.py 模块的顶部。

【讨论】:

【参考方案2】:

对于原始问题的作者,以及那些搜索“AttributeError: module has no attribute”字符串的人,根据接受的答案,常见的解释是用户创建的脚本有名称冲突带有库文件名。但是请注意,问题可能不在于生成错误的脚本的名称(如上例所示),也不在于该脚本显式导入的任何库模块的名称。可能需要一些侦探工作来找出导致问题的文件。

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

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

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

【讨论】:

【参考方案3】:

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

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

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

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

您尝试导入的模块:requests

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

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

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

【讨论】:

以上是关于从脚本导入已安装的包会引发“AttributeError:模块没有属性”或“ImportError:无法导入名称”的主要内容,如果未能解决你的问题,请参考以下文章

java链接MySQL数据库时使用com.mysql.jdbc.Connection的包会出红线问题

即使使用全新的 Anaconda 安装,使用依赖于 scipy 的包也会引发 ImportError(DLL 加载失败)

python [使用代码安装pip包]使用此脚本使用nothin而不是python代码安装python包,并列出已安装的包#

从批处理脚本中引发 Jenkins 作业中止

怎么查看python中已安装的包

为啥 Python informixdb 包会抛出错误!