我是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不能使所有模块保持一致?
答案 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
中没有任何相同的内容
所有这些子包现在都完全可用,具有属性点符号访问; 和,来自.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
,请尝试使用制表符完成。您会看到submodule1
和subpacakge1
可直接使用点表示法,但其他子包不是。
以下是另一个注释:rgb2gray
的完整路径实际上是skimage/color/colorconv/rgb2gray
。为什么可以从color
访问它?因为it's imported within the __init__.py
of color。
到你的上一个问题:
那么如何知道导入是否会以递归方式为模块工作?和 为什么Python不能使所有模块保持一致?
关于是否在内部进行这些导入,包之间没有很多可预测的一致性。通常,大&#34;嵌套&#34;像熊猫和NumPy这样的图书馆。在skimage的情况下,它的设计师可能想要保持其子包装&#34; distinct&#34;因为它们中的一些提供了非常不同的功能,即使它们与图像相关。