我正在使用通过miniconda安装的Python 3.6.5。我的问题是由于我正在点子安装与本地程序包具有相同名称空间的程序包而引起的。 pip安装此软件包后,我将无法再从本地软件包中导入。我收到一个ModuleNotFoundError
错误。如果可能的话,命名空间必须保持这种方式。
这是我的目录结构:
/root
stuff
- __init__.py
- my_stuff.py
app.py
初始化 .py
__import__('pkg_resources').declare_namespace(__name__)
app.py
from stuff.my_stuff import my_fun
这很好,直到我用相同的名称空间“ 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
之前导入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的名称空间相同的软件包的问题?
编辑:
我继续进行实验,发现删除所有__init__.py
文件时,一切正常。我遇到了这个post:从Python 3.3开始,没有__init__.py
的文件夹可以被认为是隐式命名空间包的一部分。我仍然对上面提到的行为感到困惑。
答案 0 :(得分:0)
这个SO question应该可以回答你的问题
为了方便,我仍然把原来的答案放在这里。
无法通过为 pip 指定参数来更改“导入路径”(安装名称)。但是,您可以在安装后对软件包进行一些更改:
这样使用 pip install -e git+http://some_url#egg=some-name
即使两个包的导入路径相同,它们也会保存在不同的目录下(使用 #egg= 后提供的一些名称)。之后,您可以转到包的源目录(通常为 venv/src/some-name
)并重命名一些文件夹以更改导入路径
fork 存储库,进行更改,然后从该存储库安装包。或者,您可以使用不同的名称在 PyPI 上发布您的包并使用该名称进行安装
使用 pip download
将其中一个包放入您的项目中,然后根据需要重命名文件夹