鉴于以下内容(注意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
包。
有人可以解释一下这个或者在任何地方都有记录吗?
答案 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
包。