python - 模块的导入顺序
python - order of import for modules
例如有一些文件夹:
.
├── file_a.py
├── file_b
│ └── __init__.py
└── file_b.py
其中 file_a.py
类似于:
from file_b import some_function
我知道这绝对不是一个好的做法,但后面的解析顺序是什么?
即python 如何决定为 "absolute import" 导入哪个模块?
我做了个小实验,做了somelib.py
和somelib/__init__.py
然后尝试了以下
>>> from somelib import foo
in somelib/__init__.py
>>>
显然 python 更喜欢 directory-based 模块而不是 file-based 模块
正如@scnerd 指出的那样,这可能是意外行为,但这是我在默认实现中看到的。
如果您想知道这是怎么发生的,您可能会查看 importlib 以了解可怕的细节
我不确定此信息在文档中的位置(或是否)- 在 import system docs didn't turn it up - but PEP 420 中快速检查说明如下:
While looking for a module or package named "foo", for each directory
in the parent path:
- If
<directory>/foo/__init__.py
is found, a regular package is imported and returned.
- If not, but
<directory>/foo.{py,pyc,so,pyd}
is found, a module is imported and returned. The exact list of extension varies by platform
and whether the -O flag is specified. The list here is representative.
- If not, but
<directory>/foo
is found and is a directory, it is recorded and the scan continues with the next directory in the parent
path.
- Otherwise the scan continues with the next directory in the parent path.
If the scan completes without returning a module or package, and at
least one directory was recorded, then a namespace package is created.
所以根据 PEP 420,如果在同一个目录中找到同名的包和 non-package 模块,则包胜出。
根据@JonKiparsky 的建议,我仔细研究了 importlib,最终找到了 importlib._bootstrap.FileFinder.find_spec
,它确实在查找符合包名称的有效文件之前明确检查目录。不过,很高兴看到 @user2357112 的回答,这应该是定义的行为,而不仅仅是偶然事件。
例如有一些文件夹:
.
├── file_a.py
├── file_b
│ └── __init__.py
└── file_b.py
其中 file_a.py
类似于:
from file_b import some_function
我知道这绝对不是一个好的做法,但后面的解析顺序是什么?
即python 如何决定为 "absolute import" 导入哪个模块?
我做了个小实验,做了somelib.py
和somelib/__init__.py
然后尝试了以下
>>> from somelib import foo
in somelib/__init__.py
>>>
显然 python 更喜欢 directory-based 模块而不是 file-based 模块
正如@scnerd 指出的那样,这可能是意外行为,但这是我在默认实现中看到的。
如果您想知道这是怎么发生的,您可能会查看 importlib 以了解可怕的细节
我不确定此信息在文档中的位置(或是否)- 在 import system docs didn't turn it up - but PEP 420 中快速检查说明如下:
While looking for a module or package named "foo", for each directory in the parent path:
- If
<directory>/foo/__init__.py
is found, a regular package is imported and returned.- If not, but
<directory>/foo.{py,pyc,so,pyd}
is found, a module is imported and returned. The exact list of extension varies by platform and whether the -O flag is specified. The list here is representative.- If not, but
<directory>/foo
is found and is a directory, it is recorded and the scan continues with the next directory in the parent path.- Otherwise the scan continues with the next directory in the parent path.
If the scan completes without returning a module or package, and at least one directory was recorded, then a namespace package is created.
所以根据 PEP 420,如果在同一个目录中找到同名的包和 non-package 模块,则包胜出。
根据@JonKiparsky 的建议,我仔细研究了 importlib,最终找到了 importlib._bootstrap.FileFinder.find_spec
,它确实在查找符合包名称的有效文件之前明确检查目录。不过,很高兴看到 @user2357112 的回答,这应该是定义的行为,而不仅仅是偶然事件。