import numpy和import numpy as np的区别
我明白在可能的情况下应该使用
import numpy as np
这样可以避免因为命名空间而产生的冲突。但是我注意到,下面这个命令可以正常工作
import numpy.f2py as myf2py
而下面这个却不行
import numpy as np
np.f2py #throws no module named f2py
有人能解释一下这是为什么吗?
5 个回答
这是一篇比较老的帖子,但我想分享一下我对其他人解释的看法。
numpy这个包(可以去它的git仓库看看)里面有很多子包,f2py就是其中之一,还有一些像core、ma等。
如果你查看numpy包里的init.py文件,你会看到里面有一些导入的内容,比如 -
from . import core etc
但是里面并没有导入f2py这个子包。这就是为什么像这样的语句
import numpy as np
np.f2py
是无法工作的,而
import numpy as np
np.core
则是可以工作的原因。
numpy.f2py
其实是 numpy
的一个子模块,所以需要单独导入,而不是直接从 numpy
中使用。正如aha之前提到的:
当你执行
import numpy
时,它创建了一个指向numpy
的链接,但numpy
并没有进一步链接到f2py
。只有当你执行import numpy.f2py
时,这个链接才会建立。
当你使用 import numpy as np
这行代码时,其实是把 "numpy" 简化成 "np",这样可以让你的代码更容易阅读。同时,这也能避免命名空间的问题。(比如 tkinter
和 ttk
就是一个很好的例子,说明如果有命名空间问题会发生什么,两个界面看起来会非常不同。)
这是一个语言特性。f2py
是 numpy
模块的一个子包,需要单独加载。
这个特性允许:
- 你只加载
numpy
中你需要的部分,从而加快执行速度。 f2py
的开发者可以和其他子包的开发者保持命名空间的独立。
不过要注意,使用 import numpy.f2py
或者 import numpy.f2py as myf2py
仍然是在加载父模块 numpy
。
这样说,当你运行
import numpy as np
np.f2py
你会收到一个 AttributeError
错误,因为 f2py
不是 numpy
的一个属性,因为 numpy
包的 __init__()
没有在它的范围内声明任何关于子包 f2py
的内容。
import as
这种写法是在 PEP 221 中引入的,那里有详细的说明。
当你通过
import numpy
来导入一个模块时,numpy这个包就会被绑定到本地变量 numpy
上。import as
的写法让你可以把导入的模块绑定到你自己选择的本地变量名上(通常是为了避免名字冲突、缩短冗长的模块名,或者统一访问那些有相似接口的模块)。
所以,
import numpy as np
其实和下面这段代码是一样的,
import numpy
np = numpy
del numpy
在理解这个机制时,值得记住的是,import numpy
实际上意味着 import numpy as numpy
。
当你导入一个 子模块 时,必须使用完整的父模块名称,因为导入的机制是在比本地变量范围更高的层面上进行的。也就是说,
import numpy as np
import numpy.f2py # OK
import np.f2py # ImportError
我也不同意你说的“如果可能的话应该 [import numpy as np]”。这样做主要是出于历史原因,因为人们很快就会厌倦每次操作都要加上 numpy
前缀。对我来说,这并没有避免名字冲突(程序员的懒惰实际上意味着用 np
造成冲突的概率更高)。
最后,为了总结我的观点,这里有两个你应该知道的关于 import as
机制的有趣用法:
1. 长子导入
import scipy.ndimage.interpolation as warp
warp.affine_transform(I, ...)
2. 兼容的API
try:
import pyfftw.interfaces.numpy_fft as fft
except:
import numpy.fft as fft
# call fft.ifft(If) with fftw or the numpy fallback under a common name
numpy是一个主要的包名,当你执行import numpy
时,并不会把子模块numpy.f2py
也导入进来。
当你执行import numpy
时,它会创建一个指向numpy
的链接,但这个链接并没有进一步指向f2py
。只有当你执行import numpy.f2py
时,链接才会建立。
在你上面的代码中:
import numpy as np # np is an alias pointing to numpy, but at this point numpy is not linked to numpy.f2py
import numpy.f2py as myf2py # this command makes numpy link to numpy.f2py. myf2py is another alias pointing to numpy.f2py as well
这里有import numpy.f2py
和import numpy.f2py as myf2py
之间的区别:
import numpy.f2py
- 将numpy放入本地符号表(指向numpy),并且numpy与numpy.f2py建立了链接。
- 这样numpy和numpy.f2py都可以访问。
import numpy.f2py as myf2py
- 将myf2py放入本地符号表(指向numpy.f2py)。
- 它的父级numpy没有被添加到本地符号表中。因此,你不能直接访问numpy。