Python:两个同名的包,如何指定加载哪一个?

7
我有两个安装不同包但名称相同的包。它们都是“包”,因为它们都有顶级的setup.py文件,其中在setup命令中指定了package=['foo']
如果使用distutils.core进行安装,则最后一个安装的包将覆盖先前的一个(但我认为只有当所有.py文件的名称相同时才会覆盖?)。 如果使用setuptools进行安装,则这两个包将被安装到不同的egg中。
一种选择是在导入软件包名称之前显式设置sys.path;这似乎很不符合Python惯例且不太好看。
假设我已经在setuptools的不同eggs中安装了这两个具有相同名称的包,该如何指定要导入的软件包?

好奇一下,它们是哪些包? - Steven Rumbalski
2
在我看来,如果同时安装了两个同名的包,这很不符合Pythonic的风格。 - Wooble
我想到了http://pypi.python.org/pypi/pydns和http://pypi.python.org/pypi/dnspython。一个使用DNS,而另一个使用dns作为名称。 - Zart
StevenRumbalski - 我的两个包agpy和pyspeckit中都包含了名为'mpfit'的两个包。 Wooble - 是的,说得对。我仍然认为我的问题应该有答案(目前,同名的两个包将优先选择按字母顺序排列较早的egg),但解决方法是将“packages”作为子包含在内。 - keflavich
2个回答

2

Setuptools指南提到了--multi-version(-m)开关,它完全从sys.path中删除包。您必须尽早在代码中使用pkg_resources.require('package==version')来让它修复sys.path。当使用-m时,这是easy_install总是打印的建议。

但是,除非它们使用命名空间包设计,否则您不能同时导入两个包。


这是一个不错的解决方案,但似乎只适用于“develop”命令;是否有任何“install”命令的替代方案? - keflavich
开发只是一种特定类型的原地安装。"-m" 也适用于安装。我经常使用 "easy_install -zmaxd /output/directory packagename" 从 pypi 获取软件包及其依赖项,并将它们全部构建为 egg 文件。然后,我使用 "venv/bin/easy_install -f /output/dir packagename" 将它们安装到虚拟环境或其他环境中,可以节省大量下载和构建时间。但 pip 不支持二进制 egg 文件。 - Zart
是吗?如果我尝试使用 python setup.py install -m 或者 pip install [name] -m(或者反过来安装 / -m的顺序),我会得到 error: option -m not recognized 的错误提示。这只能在 easy_install 中工作,我猜这是一个解决方法,但是如果有人使用 pip 呢? - keflavich
2
pip不支持蛋和多版本包。easy_install附带setuptools,它们是在virtualenv创建之前设计的。因此,setuptools解决了在site-dir中管理多个软件包的.pth文件的问题,而pip根本不关心并依赖于virtualenv隔离。使用pip时,您被迫使用两个不同的虚拟环境。还要注意,“setup.py develop”使用easy_install的机制,并将每个软件包安装在其自己的版本化目录中。“pip install -e .”使用pip的机制执行相同操作,并将所有内容转储到site-packages中。 - Zart

0

我认为解决问题的最佳方法是更改顶级目录的名称,除非其他软件包依赖于该软件包。

您可以通过修改setup.py或直接更改site-packages中的文件夹名称来实现此操作。蛋只是元数据。

至于设置sys.path,最好使用site模块,通过创建.pth文件。当实例化时,该文件中位于路径的任何路径都将添加到Python路径的“头”中。

这两个软件包是否不同并且命名是巧合,还是它们只是同一软件包的分支?


同一根枝干的两个分支;不同的任务需要不同的分支。 - keflavich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接