如何在setup.py中配置依赖要求至少两个指定Python包中的一个已安装?
Python 包二选一依赖配置方案
setuptools本身没有原生支持“至少安装两个依赖中的一个”的声明语法,你可以根据你的需求选择以下三种实现方式:
1. 安装时强制校验
在setup.py中添加预检查逻辑,两个依赖都不存在时直接抛出错误中断安装,示例代码如下:
from setuptools import setup from pkgutil import iter_modules # 替换为你依赖的两个模块名 DEP_A = "foo" DEP_B = "bar" has_dep_a = any(module.name == DEP_A for module in iter_modules()) has_dep_b = any(module.name == DEP_B for module in iter_modules()) if not (has_dep_a or has_dep_b): raise RuntimeError(f"安装本包需要至少安装以下依赖中的一个:{DEP_A}、{DEP_B}") setup( name="你的包名", version="1.0.0", # 其他必填的包配置项 install_requires=[ # 其他必须的固定依赖写在这里,不要加入上述两个二选一依赖 ] )
注意:该方案会在用户安装你的包时直接校验依赖状态,不符合要求就终止安装,适合对依赖要求严格的场景。
2. 配置可选依赖分组
通过extras_require给用户提供明确的安装选择入口,用户可以自行选择安装其中一个依赖,示例配置如下:
setup( name="你的包名", version="1.0.0", install_requires=[ # 其他固定依赖 ], extras_require={ "foo": ["foo>=1.0.0"], "bar": ["bar>=2.0.0"], "all": ["foo>=1.0.0", "bar>=2.0.0"] } )
用户可以通过以下命令选择对应依赖安装:
- 选择foo作为依赖:
pip install 你的包名[foo] - 选择bar作为依赖:
pip install 你的包名[bar] - 同时安装两个依赖:
pip install 你的包名[all]
3. 运行时动态校验(推荐)
不在安装阶段做拦截,而是在代码运行到对应功能时做依赖检测,对用户更友好,不会阻塞安装流程,示例代码如下:
from importlib.util import find_spec _has_foo = find_spec("foo") is not None _has_bar = find_spec("bar") is not None if not (_has_foo or _has_bar): raise ImportError( "使用该功能需要至少安装foo或bar中的一个,可执行pip install foo 或 pip install bar完成安装" ) # 自动适配已安装的依赖作为后端 if _has_foo: import foo as impl_backend else: import bar as impl_backend
推荐把第二种和第三种方案结合使用,既给用户明确的安装指引,也能避免用户误装后运行时出现不明报错。
内容的提问来源于stack exchange,提问作者emesik
相关产品推荐
相关产品推荐

