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

Tan*_*ton 10 python 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
Run Code Online (Sandbox Code Playgroud)

此命令不起作用:

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
Run Code Online (Sandbox Code Playgroud)

上面得到了这个错误:

AttributeError: 'module' object has no attribute 'matlib'
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Jam*_*han 15

简答

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

此功能的原因可能是:

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

当你导入numpy没有子包时matlib,Python将寻找.matlib作为numpy包的属性.numpy未导入时尚未分配此属性numpy.matlib(请参阅下面的讨论)

子模块和绑定

如果您想知道为什么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
Run Code Online (Sandbox Code Playgroud)

或者,如果您直接查看该__init__.py文件,numpy您将看到没有导入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)
Run Code Online (Sandbox Code Playgroud)

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

如果没有第(2)行,第(3)行中的命名空间副本只会附加到子模块.有趣的是,由于第(3)行,你仍然可以做这样一个有趣的命令.

import numpy.matlib               
numpy.matlib.np.matlib.np.array([1,1])
Run Code Online (Sandbox Code Playgroud)

这是因为,np.__all__被附接到npnumpy.matlib(其经管线进口(1)).


sha*_*678 5

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

import numpy.matlib
Run Code Online (Sandbox Code Playgroud)

或者,您可以保持第二个导入行不变,而使用:

P1 = npm.identity(V.shape[1], dtype=int)
Run Code Online (Sandbox Code Playgroud)