导入numpy和Scipy包中的模块/子包的区别

8
我正在使用Anaconda 2.1.0发行版通过scipy和numpy。我使用Spyder作为我的Python IDE。
当我运行import scipy as sp时,我无法通过sp.访问其子包,例如optimize、linalg、cluster等。
然而,当我运行import numpy as np时,我可以通过np访问它的所有子包,例如linalg、random、matrixlib、polynomial、testing等。
这两个导入方式为什么会有不同的工作方式?为什么import scipy as sp不能将所有的scipy子包都放进sp的名称空间中?

1
这确实是一个有趣的问题。有趣的是:在执行 import scipy as sp 后,输入 sp.optimize 会出现错误。但是如果你执行 from scipy import optimize,突然之间 sp.optimize 就不会再出错了。这个问题并不特定于Anaconda。 - cel
3
@cel,你不再收到错误提示是因为当你键入 from scipy import optimize 时,解释器已经意识到它已经加载了主要的包 scipy,并且将在该已加载的模块中导入子模块 optimize。标识符 sp 指向与之前相同的模块,现在已经“更新”,因此你现在也可以通过这个标识符访问子模块 optimize - gg349
@gg349,哦,那很有道理 - 我不知道 :) - cel
从历史上看,numpy是基本的、集成的数值包。scipy是一组独立开发的科学包。它们都使用了numpy,但彼此之间并不依赖。 - hpaulj
1个回答

7
这种不同导入行为的可能性是 Python 语言的设计所致。
默认情况下,模块的导入语句只会导入主模块,而不会导入子模块。主模块可能(例如在 numpy 的情况下)会导入一些或所有的子模块,也可能不会(例如在 scipy 的情况下)。这样做的原因可以通过 scipy 进行说明:在大多数情况下,您只需要使用 scipy 包中的一个子模块。这种默认行为不会使解释器加载与您的代码无关的子模块而挂起。
注意,numpy 并不默认导入所有的子模块,例如它不会加载 numpy.f2py,请参见 THIS 问题/答案了解更多细节。
在此 (*) 中,我指的是像 import scipyimport scipy as sp 这样的导入语句,其中加载了一个模块。当然,如果您写 import scipy.optimize,那么 Python 将首先加载主模块,然后加载子模块。

谢谢。那么,有什么简单的表达式可以加载用户想要的任何标识符下的任何模块的所有子模块吗? - user3317287
1
肯定有一种方法,但这是一个不好的想法。只需导入您需要的模块即可。我认为,如果您事先不知道从某个模块中需要哪些子模块,则意味着您存在更大的问题,因为您不知道自己在做什么。 - gg349
你可能会对这个问题感兴趣。 - gg349
我也在尝试做这个,但是我无法加载插值子模块。它显示了这个错误信息:“ImportError: DLL load failed: The specified module could not be found.” - Ipa

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