为什么Python会出现AttributeError错误?

47

有一件事情,我不明白。

为什么这样

import scipy # happens with several other modules, too. I took scipy as an example now...

matrix = scipy.sparse.coo_matrix(some_params)

产生这个错误:

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

3
好的,我会尽力进行翻译。有什么让人困扰的地方吗?如果模块中不存在“sparse”,你希望会发生什么? - Paul Manta
1
我没有意识到sparse是scipy的一个子模块,并且子模块不会自动导入 - 正如@David Zaslavsky在下面指出的那样。 - Aufwind
17
投反对票的人应该解释为什么他们投反对票,我不明白这个问题有什么问题。事实上,我认为这是一个非常好的问题。 - juliomalegria
1
谢谢@julio.alegria,从另一个人那里听到这样的话感觉很好。 :-) - Aufwind
4个回答

63
这是因为scipy模块没有名为sparse的属性。只有在你导入scipy.sparse时才会定义该属性。
子模块不会在你仅仅导入import scipy时自动导入; 你需要显式地导入它们。大多数包都遵循这个规���,虽然一个包可以选择导入自己的子模块。例如,如果scipy/__init__.py包含语句import scipy.sparse,那么只要你导入scipysparse子模块就会被导入。

1
我不知道子模块不会自动导入。谢谢! - Aufwind
1
实际上,子模块是否自动导入取决于软件包。 - Ethan Furman
@Ethan:没错,我已经在答案中编辑了一条注释来说明这一点。 - David Z
6
值得注意的是,这主要是由于大小写不敏感的文件系统(例如 Windows)的存在。在这样的系统上,很难知道一个名为“sparse.py”的文件应该被导入为叫做sparseSparseSParse还是sParse的一个模块(如果它与解析S表达式有关,也许就更麻烦了)。Python通过要求显式导入来告诉它正确的名称(可以在程序中或包的__init__.py中进行),从而保证了在区分大小写和不区分大小写的文件系统上具有一致的行为。 - Ben
1
@Ben,我觉得你的回答是这个问题中最好的答案。 - tumultous_rooster

5
因为您导入的是scipy而不是sparse。尝试使用from scipy import sparse

这个改变是什么时候发生的?以前还能够使用sp.sparse。 - BirdLaw

4

当对象的属性不可用时,会引发AttributeError

属性引用是由主体、句点和名称组成的:

attributeref ::= primary "." identifier

要返回该对象的有效属性列表,请使用dir(),例如:

dir(scipy)

所以你可能只需要做这个简单的步骤:import scipy.sparse


-3
Python 中的默认命名空间是 "__main__"。当你使用 "import scipy" 时,Python 会创建一个与你的模块名称不同的命名空间。 在 Python 中的规则是:当你想从另一个命名空间调用属性时,你必须使用完全限定的属性名称。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接