什么时候导入'在Python中递归地工作

时间:2018-02-26 02:35:33

标签: python

我是Python的新手,并且是' import'在Python中令我困惑。它似乎有时会递归地导入模块中的函数,有时也不会。

例如,如果我这样做

import numpy

然后我可以使用numpy中的所有函数,包括'子模块中的函数' (不确定它是否是正确的名称),例如

a = numpy.fft.fft2(b)
c = numpy.random.rand()

然而,如果我这样做

import skimage

我不能在'子模块中使用功能'滑雪,如

skimage.color.rgb2gray()
skimage.transform.resize()

我必须导入'子模块'明确地作为

from skimage import color
from skimage import transform

那么如何知道导入是否会以递归方式为模块工作?为什么Python不能使所有模块保持一致?

1 个答案:

答案 0 :(得分:2)

您所看到的并非递归。这是一些将一些函数带入子模块的命名空间的情况。

来自滑雪docs

  

skimage的主要包只提供了一些用于在图像数据类型之间进行转换的实用程序;对于大多数功能,您需要导入以下子包之一...

简而言之,color不是一个模块;它是一个完全真实的包装内包装。包__init__.py定义了进入其命名空间的内容。当你看到" skimage没有属性'"',那是因为顶级包裹skimage只提供这些东西:

[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']

现在,请查看__init__.py from NumPy

from . import core
from .core import *
from . import compat
from . import lib
from .lib import *
from . import linalg
# ... and so on

skimage __init__.py

中没有任何相同的内容

所有这些子包现在都完全可用,具有属性点符号访问; ,来自.lib的所有函数现在也可通过np.<function>访问,因为它们也会在此处导入。

您可以通过简单的嵌套包结构为自己看到这种差异。在您的本地驱动器上进行此操作:

sound/
    __init__.py
    subpackage1/
        __init__.py
        submodule1.py
    subpackage2/
        __init__.py
        submodule2.py

现在,在顶级__init__.py中,只放from sound.subpackage1 import submodule1。 (不要参考subpackage2。)现在,如果你cd进入声音之上的一个级别并执行import sound,请尝试使用制表符完成。您会看到submodule1subpacakge1可直接使用点表示法,但其他子包不是。

以下是另一个注释:rgb2gray的完整路径实际上是skimage/color/colorconv/rgb2gray。为什么可以从color访问它?因为it's imported within the __init__.py of color

到你的上一个问题:

  

那么如何知道导入是否会以递归方式为模块工作?和   为什么Python不能使所有模块保持一致?

关于是否在内部进行这些导入,包之间没有很多可预测的一致性。通常,大&#34;嵌套&#34;像熊猫和NumPy这样的图书馆。在skimage的情况下,它的设计师可能想要保持其子包装&#34; distinct&#34;因为它们中的一些提供了非常不同的功能,即使它们与图像相关。