我正在编写一个依赖于特定模块的python program。事实是,PyPI中至少有两个不同的包有一个名为rtmidi和python-rtmidi的模块。它们提供几乎相同的功能,但语法不同
当只安装了“正确”的软件包时,一切正常。但是如果两个包都安装了,使用import rtmidi
加载“错误”的模块,我的程序就会崩溃。让它重新工作的唯一方法是卸载这两个软件包,然后重新安装正确的软件包。当然,由于用户可能会依赖其他模块来执行其他程序,我不能期望他们这样做
尝试用rtmidi.__name__
标识模块会对两个包产生相同的结果
所以我的问题是,我该如何解决这个名称冲突问题?有没有最佳实践方法来处理这个问题
我想你应该看看你不想要的,然后删除它,然后再尝试导入它。 您可以在站点包文件夹中找到包
不能同时安装它们(如果依赖默认的
pip
行为)。在这里,我将用两个简单的纯Python包来演示,它们有一个导入名称冲突:coveralls
和python-coveralls
这些是
python-coveralls
的内容。请注意,实际的__init__.py
文件位于site-packages/coveralls/
目录中这些是
coveralls
的内容python-coveralls
已被覆盖。请注意,这是相同的文件。旧__init__.py
里的任何东西都不见了那里仍然有一个包的幽灵,但是它的内容不见了(除了所有包内部都有的东西)。注意,文件现在是
None
:这个包没有__init__.py
文件您也可以通过运行
pip uninstall python-coveralls
然后重新安装任意程序来解除对环境的阻塞解决方案
您必须要求您的用户只使用您需求中的软件包,但这就是我们使用虚拟环境的原因。或者,想要直接使用另一个包的用户可以使用^{} option to ^{} 更改安装位置(以及加载时使用的名称)(但这对使用另一个库的其他应用程序没有帮助)
实际上,最好将此作为安装过程的一部分。您需要(a)告诉用户需要安装什么要求;或者(b)有一些自动化的过程来满足正确的需求
我认为最佳实践是(b)。一种常见的方法是使用
setuptools
,并为setup
函数定义install_requires
参数。这是指PyPI上的包名,而不是导入名The setuptools quickstart是一个很好的起点以下内容基于hoefling的评论和dwhswenson的回答(后者很好地解释了问题所在)
将其标记给项目所有者,以便他们更改其模块的名称。从理论上讲,这是迄今为止最好的解决方案,因为它不仅可以解决您的问题,还可以将其他人从中解救出来,这符合模块开发人员的最佳利益。在实践中,它打开了一整罐蠕虫,让人们知道应该改哪个名字
或在项目中包含模块,也称为vendoring,并使用路径
my_project/_vendor/the_module
导入它(或在sys.path
中首先添加该路径)。如果模块只是一个.py文件,并且许可证允许,这是解决问题的最简单方法。在我的例子中,这是不可行的,因为我需要的模块包括一些需要编译的C代码,包括整个源代码,然后要求用户编译它似乎是一个大问题。所以我必须这样做:或告诉用户在项目的文件夹中安装模块。使用
pip
选项--target
以及项目中的文件夹路径,您可以获得自己的模块副本,而不会覆盖系统。然后,您可以在导入之前检查该文件夹是否存在。如果是,则从那里导入模块,如果不是,则可以检查系统安装的模块是否正确,如果不正确,则提示用户下面是我如何在项目中实现代码的一个粗略示例。它取代了
import rtmidi
注意:我应该只
try
导入本地文件夹模块,而不是使用条件语句,并使用路径my_project/_vendor/rtmidi
相关问题 更多 >
编程相关推荐