【问题标题】:pip installing a package with the same namespace as a local packagepip 安装与本地包具有相同命名空间的包
【发布时间】:2020-01-11 10:22:02
【问题描述】:

我使用的是 Python 3.6.5,通过 miniconda 安装。我的问题是由于我正在 pip 安装一个与本地包具有相同名称空间的包。 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

一切都按预期进行。即如果我在stuff.my_stuff 之前导入some_stuff.more_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 的文件夹可以被认为是隐式命名空间包的一部分。不过,我仍然对上述行为感到困惑。

【问题讨论】:

标签: python


【解决方案1】:

这个SO question应该回答你的问题

为方便起见,我仍然将原始答案放在这里。


无法通过为 pip 指定参数来更改“导入路径”(安装名称)。但是,您可以在安装后对包进行一些更改:

  • 这样使用pip install -e git+http://some_url#egg=some-name 即使两个包具有相同的导入路径,它们也会被保存在不同的目录下(使用#egg= 之后提供的一些名称)。之后你可以去包的源目录(通常是venv/src/some-name)并重命名一些文件夹来改变导入路径

  • fork 存储库,进行更改,然后从该存储库安装包。或者您可以使用不同的名称在 PyPI 上发布您的包并使用该名称安装它

  • 使用pip download 将其中一个包放入您的项目中,然后根据需要重命名文件夹

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-27
    • 2015-03-14
    • 1970-01-01
    • 2015-05-21
    • 2014-01-12
    • 1970-01-01
    • 2018-04-27
    • 2017-07-18
    相关资源
    最近更新 更多