Python 尝试从展开的命名空间导入模块时发生ModuleNotFoundError
假设我的项目结构如下:Python 尝试从展开的命名空间导入模块时发生ModuleNotFoundError,python,python-3.x,python-import,Python,Python 3.x,Python Import,假设我的项目结构如下: proj ├── __init__.py └── core ├── __init__.py └── a ├── __init__.py └── foo.py 其中,只有以下非空文件: # proj/__init__.py from . core import a 及 及 我的想法是将模块a从core中取出,并将其暴露在包的顶层。但是,以下操作失败: >>> from proj.a
proj
├── __init__.py
└── core
├── __init__.py
└── a
├── __init__.py
└── foo.py
其中,只有以下非空文件:
# proj/__init__.py
from . core import a
及
及
我的想法是将模块a
从core
中取出,并将其暴露在包的顶层。但是,以下操作失败:
>>> from proj.a import Bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'proj.a'
两个问题:
proj.a
导入,就好像它是proj.core.a
首先,让我们排除一个简单的问题:
import proj.a.Bar as Bar
无法工作,因为Bar
是一个类,而不是一个模块<出于同样的原因,代码>将项目核心a.Bar导入为Bar也不起作用
现在用于从项目a
导入。您使用\uuu init\uuuuuuuuuuuuuupy
文件描述的“提升”过程只创建了一个别名-在proj.\uuuuu dict\uuuuuuu
中添加的条目“a”现在绑定到一个模块对象,但其本身并不使模块proj.core.a
成为proj
的直接子模块
名称“a”只是绑定在两个不同的名称空间中:在proj.\uuu dict\uu
和proj.core.\uu dict\uu
中。来自项目的导入语句。导入条
的处理方式仍与通常相同,尝试查找具有完全限定名proj.a
的模块。Python将从和中选择import machinery(它将使用PathFinder
和FileFinder
),然后搜索类似于proj/a
的dir/subdir,但没有找到
proj.a
导入,就好像它是proj.core.a
sys.modules
dict中。尝试以下解决方法:
# proj/__init__.py
from . core import a
import sys
sys.modules[f"{__name__}.a"] = a
现在,从项目导入。导入条
可以成功,即使尚未导入proj
您正在劫持importlib,因此Python会主动启用此技巧。甚至还有,因为stdlibxml和etree也依赖于这种行为。虽然源代码注释称之为“疯狂”,但请谨慎使用 首先,让我们省去一个简单的问题:
import proj.a.Bar as Bar
无法工作,因为Bar
是一个类,而不是一个模块<出于同样的原因,代码>将项目核心a.Bar导入为Bar也不起作用
现在用于从项目a
导入。您使用\uuu init\uuuuuuuuuuuuuupy
文件描述的“提升”过程只创建了一个别名-在proj.\uuuuu dict\uuuuuuu
中添加的条目“a”现在绑定到一个模块对象,但其本身并不使模块proj.core.a
成为proj
的直接子模块
名称“a”只是绑定在两个不同的名称空间中:在proj.\uuu dict\uu
和proj.core.\uu dict\uu
中。来自项目的导入语句。导入条
的处理方式仍与通常相同,尝试查找具有完全限定名proj.a
的模块。Python将从和中选择import machinery(它将使用PathFinder
和FileFinder
),然后搜索类似于proj/a
的dir/subdir,但没有找到
proj.a
导入,就好像它是proj.core.a
sys.modules
dict中。尝试以下解决方法:
# proj/__init__.py
from . core import a
import sys
sys.modules[f"{__name__}.a"] = a
现在,从项目导入。导入条
可以成功,即使尚未导入proj
您正在劫持importlib,因此Python会主动启用此技巧。甚至还有,因为stdlibxml和etree也依赖于这种行为。虽然源代码注释称之为“疯狂”,但请谨慎使用
>>> import proj.a.Bar as Bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'proj.a'
>>> from proj.core.a import Bar
# proj/__init__.py
from . core import a
import sys
sys.modules[f"{__name__}.a"] = a