我是Python的新手,而Python中的'导入'使我感到困惑。似乎有时会递归地在模块中导入功能。
例如,如果我做
import numpy
然后我可以在numpy中使用所有功能,包括"子模块"中的功能(不确定它是专有名称(,例如
a = numpy.fft.fft2(b)
c = numpy.random.rand()
但是,如果我做
import skimage
i不能在
的"子模块"中使用功能skimage.color.rgb2gray()
skimage.transform.resize()
我必须将"子模块"明确导入为
from skimage import color
from skimage import transform
那么,如何知道导入是否会递归地用于模块?为什么python并不使所有模块都保持一致?
您看到的不是递归。在这种情况下,将某些功能带入了子模型的命名空间。
摘要文档:
skimage
的主要软件包仅提供了一些用于在图像数据类型之间转换的实用程序。对于大多数功能,您需要导入以下子弹之一...
简而言之,color
不是模块。它是一个带有包装的诚实包装。软件包的__init__.py
定义了被带入其名称空间的内容。当您看到"弹丸没有属性'颜色'"时,那是因为顶级软件包猛击只有这些东西可用:
[f for f in dir(skimage) if not f.startswith('_')]
['data_dir',
'doctest',
'doctest_verbose',
'dtype_limits',
'img_as_bool',
'img_as_float',
'img_as_int',
'img_as_ubyte',
'img_as_uint',
'pkg_dir',
'test',
'test_verbose',
'util']
现在,从Numpy查看__init__.py
:
from . import core
from .core import *
from . import compat
from . import lib
from .lib import *
from . import linalg
# ... and so on
(在弹丸__init__.py
中没有做任何等效的(
现在,所有这些子包都可以完全使用属性点通知访问;和,.lib
的所有 function 现在也可以通过np.<function>
来访问,因为它们也在这里导入。
您可以通过简单的嵌套软件包结构为自己看到这种差异。在您的本地驱动器上进行此操作:
sound/
__init__.py
subpackage1/
__init__.py
submodule1.py
subpackage2/
__init__.py
submodule2.py
现在,在顶级__init__.py
中,仅放置from sound.subpackage1 import submodule1
。(不要引用SubPackage2。(现在,如果您将cd
分为声音上方的一个级别,并且DO import sound
,请尝试使用选项卡完成。您会看到submodule1
和subpacakge1
直接使用DOT表示法,但另一个子包不是。
这是另一个注意:rgb2gray
的完整路径实际上是skimage/color/colorconv/rgb2gray
。为什么可以从color
访问?因为它是在颜色的__init__.py
中导入的。
到您的最后一个问题:
那么,如何知道导入是否会递归地用于模块?和 为什么python不能使所有模块都保持一致?
包装之间在包裹是否在内部进行这些进口方面没有太多可预测的一致性。通常,大型"嵌套"库,例如熊猫和numpy。在略读的情况下,其设计师可能想保持其子包"独特",因为其中一些具有不同的功能,即使它们与图像相关。