在Python 3.4中导入子目录意味着什么?

时间:2014-02-25 09:12:02

标签: python-3.x package

我认为包应始终包含__init__.py文件。但这似乎对我有用。

C:\Windows>python
Python 3.4.0b3 (v3.4.0b3:a97ce3ecc96a, Jan 26 2014, 17:50:55) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import System32
>>>

即使我没有任何 init .py文件,import System32如何成功?

看起来我也可以从子目录导入包并使用它,就像子目录是一个有效的Python包一样。

C:\Windows>echo def bar(): print('hi') > System32\foo.py

C:\Windows>python
Python 3.4.0b3 (v3.4.0b3:a97ce3ecc96a, Jan 26 2014, 17:50:55) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import System32.foo
>>> System32.foo.bar()
hi

是否可以帮助我理解为什么子目录即使没有__init__.py也会像包一样?官方文档中的引用会很棒!

1 个答案:

答案 0 :(得分:2)

我进行了一些研究,以找出这种奇怪行为的原因是什么。我的研究揭示了三件事:

  1. 它跨平台工作。我在linux上,你在Windows上。
  2. 它在python 2.7
  3. 中不起作用
  4. 没有__init__.py文件的软件包由_frozen_importlib.NamespaceLoader
  5. 加载

    这表明这种行为与名称空间有关。经过一些谷歌搜索后,我找到了它的文档:

      

    命名空间包

         

    命名空间包是各个部分的组合,其中每个部分为父包提供子包。部分可以驻留在文件系统上的不同位置。也可以在zip文件,网络或Python导入期间搜索的任何其他位置找到部分。命名空间包可能或可能不直接对应于文件系统上的对象;它们可能是没有具体表示的虚拟模块。

         

    命名空间包不会将普通列表用于路径属性。它们使用自定义可迭代类型,如果其父包的路径(或顶级包的sys.path)发生更改,它将在该包中的下一次导入尝试时自动执行对包部分的新搜索。

         

    使用命名空间包时,没有父/ init .py文件。实际上,在导入搜索期间可能会找到多个父目录,其中每个目录由不同的部分提供。因此,父/一可能不在物理上位于父/二旁边。在这种情况下,只要导入顶级父包或其中一个子包,Python就会为其创建一个命名空间包。

    您可以在文档here中阅读。还有PEP here