如果我只是从numpy模块引用它,为什么我必须从numpy导入它



哈哈!

我有两块代码,一块有效,另一块无效。唯一的区别是我不使用的numpy模块的注释行代码。当我从未引用"npm"时,为什么需要导入该模型?

此命令有效:

import numpy as np
import numpy.matlib as npm
V  = np.array([[1,2,3],[4,5,6],[7,8,9]])
P1 = np.matlib.identity(V.shape[1], dtype=int)
P1

此命令无效:

import numpy as np
#import numpy.matlib as npm
V  = np.array([[1,2,3],[4,5,6],[7,8,9]])
P1 = np.matlib.identity(V.shape[1], dtype=int)
P1

上面得到这个错误:

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

提前感谢!

简短回答

这是因为numpy.matlibnumpy的可选子包,必须单独导入。

此功能的原因可能是:

  • 特别是对于numpynumpy.matlib子模块重新定义了numpy的函数,以返回矩阵而不是ndarrays,这是许多人可能不想要的可选功能
  • 更一般地说,在不加载可能缓慢加载的模块的情况下加载父模块,而许多用户可能并不经常需要该模块
  • 可能是命名空间分离

当只导入numpy而不导入子包matlib时,Python将查找.matlib作为numpy包的属性。在未导入numpy.matlib的情况下,尚未将此属性分配给numpy(请参阅下面的讨论)

子模块和绑定

如果您想知道为什么np.matlib.identity在不使用关键字npm的情况下工作,那是因为当您导入子模块matlib时,父模块numpy(在您的情况下命名为np)将被赋予绑定到子模块的属性matlib。只有当您首先定义numpy时,这才有效。

参考:

当使用任何机制加载子模块时(例如importlib API、import或import-from语句,或内置的import()),会在父模块的命名空间中放置到子模块对象的绑定。

导入和__init__.py

导入内容的选择在模块目录中的模块各自的__init__.py文件中确定。您可以使用dir()函数来查看各个模块定义的名称。

>> import numpy
>> 'matlib' in dir(numpy)
# False
>> import numpy.matlib
>> 'matlib' in dir(numpy)
# True

或者,如果直接查看numpy__init__.py文件,则会发现matlib没有导入。

跨子模块的命名空间

如果您想知道命名空间是如何在上顺利复制的

matlib源代码运行此命令以在numpy命名空间上复制:

import numpy as np                                    # (1)
...
# need * as we're copying the numpy namespace
from numpy import *                                   # (2)
...
__all__ = np.__all__[:] # copy numpy namespace        # (3)

第(2)行,from numpy import *尤为重要。因此,您会注意到,如果只导入numpy.matlib,您仍然可以使用所有numpy模块,而无需导入numpy

如果没有第(2)行,第(3)行中的名称空间副本将仅附加到子模块。有趣的是,由于第(3)行,您仍然可以执行这样一个有趣的命令。

import numpy.matlib               
numpy.matlib.np.matlib.np.array([1,1])

这是因为np.__all__连接到numpy.matlibnp(通过线路(1)导入)。

您从未使用npm,但您确实使用了np.matlib,因此您可以将第二条导入行更改为:

import numpy.matlib

或者你可以保留你的第二条进口线,但使用:

P1 = npm.identity(V.shape[1], dtype=int)

不使用np.identity有什么原因吗?

P1 = np.identity(V.shape[1], dtype=int)

此模块包含numpy命名空间中的所有函数,以及以下返回矩阵而不是ndarrays的替换函数。

除非您与2dnp.matrix子类绑定,否则最好坚持使用常规的ndarray版本。

(其他人指出,导入原因是基于numpy__init__规范。numpy导入了大部分,但不是所有的子模块。它没有自动导入的子模块使用频率较低。这是一种礼貌的说法,You don't really need this module)

最新更新