【问题标题】:Why do I have to import this from numpy if I am just referencing it from the numpy module如果我只是从 numpy 模块中引用它,为什么我必须从 numpy 导入它
【发布时间】:2017-01-24 01:05:35
【问题描述】:

你好!

我有两个代码块,一个可以工作,一个不能工作。唯一的区别是我不使用的 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'

提前致谢!

【问题讨论】:

  • “此命令不起作用” 不是有效的问题陈述。 如何它不起作用?它会给出不正确的结果吗?它有例外吗?错误消息的存在是有原因的:为您提供有关错误原因的线索。如果您排除它们,您只是浪费了仔细编写该错误消息的程序员以及我们的时间。
  • 没问题,这里是错误信息:-------------------------------- ------------------------------ AttributeError Traceback(最近一次调用最后) () 3 4 V = np.array([[1,2,3],[4,5,6],[7,8,9]]) - ---> 5 P1 = np.matlib.identity(V.shape[1], dtype=int) 6 P1 AttributeError: 'module' object has no attribute 'matlib'
  • 这是一个常见的成语。默认情况下,包不导入可选的子包。在使用它之前你必须这样做。
  • 但您确实引用了np.matlib,只是没有使用别名npm(可选)
  • 关于子包的 cmets 帮助我理解了为什么会出现错误。谢谢!

标签: python numpy


【解决方案1】:

简答

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

这个功能的原因可能是:

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

当您只导入 numpy 而没有子包 matlib 时,Python 将寻找 .matlib 作为 numpy 包的属性。在没有导入 numpy.matlib 的情况下,该属性尚未分配给 numpy(参见下面的讨论)

子模块和绑定

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

来自reference

当使用任何机制(例如 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

或者,如果您直接查看__init__.py file for numpy,您会发现matlib 没有导入。

跨子模块的命名空间

如果你想知道命名空间是如何顺利复制的;

matlib source code 运行此命令以复制 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) 行导入)。

【讨论】:

  • 已编辑:更正了我为什么可以使用函数np.matlib.identity() 而不必使用npm 名称和命名空间的东西。
【解决方案2】:

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

import numpy.matlib

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

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

【讨论】:

    【解决方案3】:

    你有什么理由不使用np.identity

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

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

    除非您与 2d np.matrix 子类结婚,否则最好坚持使用常规的 ndarray 版本。

    (其他人指出导入原因是基于 numpy__init__ 规范。numpy 导入最多,但不是所有子模块。它不自动导入的那些使用较少。这是一种礼貌的说法,You don't really need this module)

    【讨论】:

    • 你说得对,我应该使用它,现在就是。只是想知道为什么它首先会出错。谢谢评论!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    • 2020-12-14
    • 1970-01-01
    • 2014-09-05
    • 2012-01-24
    相关资源
    最近更新 更多