python - 两个pip安装的模块同名,如何选择加载哪一个?
问题描述
我正在编写一个依赖于特定模块的 python程序rtmidi
, . 问题是,PyPI 中至少有两个不同的包有一个名为rtmidi和python-rtmidi的模块。它们提供几乎相同的功能,但语法不同。
当只安装“正确”的包时,一切正常。但是如果两个软件包都安装了,使用import rtmidi
加载“错误”模块并且我的程序崩溃。让它再次工作的唯一方法是卸载这两个软件包,然后重新安装正确的软件包。当然,由于用户可能依赖其他模块来执行其他程序,我不能指望他们这样做。
尝试rtmidi.__name__
用两个包来识别模块会得到相同的结果。
所以我的问题是,我该如何解决这个名称冲突问题?是否有最佳实践方法来处理此问题?
解决方案
您不能同时安装它们(如果依赖默认pip
行为)。在这里,我将使用几个简单的纯 Python 包进行演示,它们存在导入名称冲突:coveralls
和python-coveralls
.
# in a fresh environment
pip install python-coveralls
python -c "import coveralls; print(dir(coveralls)); print(coveralls.__file__)"
# ['__author__', '__builtins__', '__cached__', '__classifiers__', '__copyright__',
# '__doc__', '__docformat__', '__file__', '__license__', '__loader__', '__name__',
# '__package__', '__path__', '__spec__', '__version__', 'parse_args', 'wear']
# /path/to/lib/python3.8/site-packages/coveralls/__init__.py
这些是 的内容python-coveralls
。请注意,实际__init__.py
文件位于site-packages/coveralls/
目录中。
pip install coveralls
python -c "import coveralls; print(dir(coveralls)); print(coveralls.__file__)"
# ['Coveralls', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
# '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__',
# 'api', 'exception', 'git', 'reporter', 'version']
# /path/to/lib/python3.8/site-packages/coveralls/__init__.py
这些是 的内容coveralls
。python-coveralls
已被覆盖。请注意,这是同一个文件。旧时__init__.py
的任何东西都没有了。
pip uninstall coveralls
python -c "import coveralls; print(dir(coveralls)); print(coveralls.__file__)"
# ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__',
# '__spec__']
# None
那里仍然有包的幽灵,但它的内容已经消失(所有包内部都有的东西除外)。请注意,文件现在是None
:此包没有__init__.py
文件。
您可以通过运行pip uninstall python-coveralls
然后重新安装任何您想要的来解除您的环境。
解决方案
您确实必须要求您的用户只使用您要求中的包,但这就是我们使用虚拟环境的原因。或者,想要直接使用其他包的用户可以使用--target
选项pip
更改安装位置(以及加载时使用的名称) (但这不会帮助使用其他库的其他应用程序)。
在实践中,最好将此视为安装过程的一部分。您需要 (a) 告诉您的用户他们需要安装什么要求;或 (b) 有一些自动化流程来获得正确的要求。
我会说最佳做法是(b)。一种常见的方法是使用setuptools
, 并定义函数的install_requires
参数setup
。这指的是 PyPI 上的包名称,而不是导入名称。setuptools 快速入门是一个很好的起点。
推荐阅读
- php - 在子主题中重新声明函数
- python - 为什么我的手工 numpy 神经网络不学习?
- python - matplotlib 在自己的轴内更改颜色条高度
- pandas - 在多元线性回归 Python 中处理分类变量和数值变量
- apache-spark - 无法在 Zeppelin 中使用 JohnSnowLabs 预训练模型
- html - 视差模板中的中心 Div/section 元素
- postgresql - 是否有可能在 JPA 中使用来自 PostgreSQL 的 @> 运算符?
- wordpress - 除了查看“历史”时,身体是空的
- java - 在从数据库中获取详细信息之前,Android 适配器正在加载
- php - .htaccess 文件在将根文件夹重定向到文件时返回 404 错误