我使用的是 Python 3.6.5,通过 miniconda 安装。我的问题是由于我正在安装一个与本地包具有相同命名空间的包。 pip 安装此包后,我无法再从本地包导入。我收到一个ModuleNotFoundError
错误。如果可能的话,命名空间需要保持这种方式。
这是我的目录结构:
/root
stuff
- __init__.py
- my_stuff.py
app.py
init.py
__import__('pkg_resources').declare_namespace(__name__)
app.py
from stuff.my_stuff import my_fun
这工作正常,直到我 pip 安装具有相同名称空间“stuff”的包。 pip 安装包后,导入语句,from stuff.my_stuff import my_fun
抛出以下错误:ModuleNotFoundError: No module named 'stuff.my_stuff'
。我有点明白为什么了。在Python中导入模块时,它会首先查找内置模块,然后是sys.path、PYTHONPATH等......
这是真正让我困惑的部分。如果我创建另一个任意本地模块,例如some_stuff
, 如下所示:
/root
stuff
- __init__.py
- my_stuff.py
some_stuff
- __init__.py
- more_stuff.py
app.py
如果我然后运行:
app.py
from some_stuff.more_stuff import more_fun
from stuff.my_stuff import my_fun
一切都按预期进行。即如果我导入some_stuff.more_stuff
before stuff.my_stuff
,一切正常。但反之则不然。独家进口stuff.my_stuff
导致ModuleNotFoundError
.
app.py
# The code above works, but this causes the error
from stuff.my_stuff import my_fun
是什么导致了这种行为?如何解决本地引用与 pip 安装的名称空间相同的包的问题?
Edit:
我继续试验并注意到当我删除所有__init__.py
文件,一切都按预期进行。我遇到了这个post https://stackoverflow.com/questions/37974843/why-can-i-import-successfully-without-init-py:从Python 3.3开始,一个没有后缀的文件夹__init__.py
可以被视为隐式名称空间包的一部分。但我仍然对上面提到的行为感到困惑。