Python 3导入优先级与__init __。py

时间:2018-04-30 23:32:44

标签: python python-3.x

鉴于以下内容(注意test错误地在test包中构建了阴影,我应将其命名为tests,我们将在稍后的问题中再次讨论<) / p>

├── test
│   └── test_request_billing_id.py
└── requets_billing_id.py

在Python shell中,尝试运行from test import test_request_billing_id 它提供了ImportError: cannot import name 'test_request_billing_id',它试图导入内置的test包而不是我自己的test文件夹。

可以通过运行有效导入

来验证

from test import support

问题1:

鉴于Python3允许implicit namespace packages,这意味着我的test文件夹也是一个包,我想内置test包的优先级高于我自己的test包?

问题2:

我在自己的__init__.py文件夹中创建了test,如下所示:

├── test
│   ├── __init__.py
│   └── test_request_billing_id.py
└── requets_billing_id.py

再次运行相同的import语句,它工作正常。

from test import test_request_billing_id

通过运行此无效导入

来验证内置投影test

from test import support会出错:ImportError: cannot import name 'support'

在我看来,让__init__.py告诉python解释器使我的test阴影成为内置的test包。

有人可以解释一下这个或者在任何地方都有记录吗?

1 个答案:

答案 0 :(得分:1)

是的,具有__init__.py的包优先。这在PEP的this section中有解释:

  

在导入处理期间,导入机器将继续   迭代父路径中的每个目录,就像在Python中一样   3.2。在寻找名为“foo”的模块或包时,对于父路径中的每个目录:

     
      
  • 如果找到<directory>/foo/__init__.py,则会导入并返回常规包。
  •   
  • 如果没有,但找到<directory>/foo.{py,pyc,so,pyd},则会导入并返回模块。扩展名的确切列表因平台而异   以及是否指定了-O标志。这里的清单具有代表性。
  •   
  • 如果没有,但找到<directory>/foo并且是一个目录,则会记录该目录并继续扫描父目录中的下一个目录   路径。
  •   
  • 否则,扫描将继续执行父路径中的下一个目录。
  •   

如果在搜索过程中遇到任何命名空间包,则会“记录”它们并继续搜索。如果稍后找到包含__init__.py的包,则会丢弃“已记录”的命名空间包,而是导入包含__init__.py的包。

这正是当您的test包没有__init__.py时所发生的情况 - 标准库中的test__init__.py ,因此它优先于您的命名空间test包。