如何在setup.py的install_requires中声明二选一的依赖项
这个问题问得好!这种“二选一”的依赖场景在处理功能等价的包(比如TensorFlow的CPU和GPU版本)时非常常见,而且完全可以在setup.py中实现。下面我会根据不同的使用场景,给你介绍几种最实用的方案:
方案1:使用PEP 508的逻辑或语法(推荐,简洁直接)
从setuptools 42.0.0和pip 19.0版本开始,支持PEP 508定义的||逻辑或运算符,你可以直接在install_requires里这样写:
from setuptools import setup setup( name="my_module", version="0.1.0", install_requires=[ # 表示只要安装了tensorflow>=2.0 或者 tensorflow-gpu>=2.0中的任意一个即可 "tensorflow>=2.0 || tensorflow-gpu>=2.0" ], # 其他配置项... )
当用户执行pip install my_module时,pip会先检查当前环境里是否已经有满足版本要求的tensorflow或tensorflow-gpu。如果其中一个已经存在,就不会重复安装;如果都没装,pip会默认安装列表里的第一个选项(也就是TensorFlow的CPU版本)。
要是你想让pip优先安装GPU版本(针对支持GPU的环境),只需要把tensorflow-gpu放在前面就行:
install_requires=[ "tensorflow-gpu>=2.0 || tensorflow>=2.0" ]
方案2:用额外依赖(extras_require)让用户主动选择
如果希望给用户更多控制权,让他们可以明确选择安装CPU还是GPU版本的依赖,可以用extras_require定义可选的依赖组:
from setuptools import setup setup( name="my_module", version="0.1.0", # 这里不强制添加TensorFlow依赖,让用户自行选择 install_requires=[ # 你的其他必填依赖写在这里 ], extras_require={ "cpu": ["tensorflow>=2.0"], "gpu": ["tensorflow-gpu>=2.0"] } )
用户就可以根据自己的需求安装:
- 安装CPU版本依赖:
pip install my_module[cpu] - 安装GPU版本依赖:
pip install my_module[gpu]
如果想默认安装CPU版本,同时保留GPU选项,可以把tensorflow>=2.0加到install_requires里,然后在GPU的额外依赖里加一个冲突规则,避免同时安装两个版本:
extras_require={ "gpu": [ "tensorflow-gpu>=2.0", # 确保CPU版本不会和GPU版本同时安装 "tensorflow==0.0.0; python_version>='3.6'" ] }
方案3:动态检测已安装包(进阶用法)
如果你希望安装时自动检测环境中已有的包,完全避免重复安装,可以在setup.py里动态检查已安装的依赖,然后生成对应的install_requires列表:
from setuptools import setup import pkg_resources def get_tensorflow_dep(): # 检查是否已经安装了tensorflow或tensorflow-gpu try: pkg_resources.get_distribution("tensorflow") # 已经安装了CPU版本,不需要添加依赖 return [] except pkg_resources.DistributionNotFound: try: pkg_resources.get_distribution("tensorflow-gpu") # 已经安装了GPU版本,不需要添加依赖 return [] except pkg_resources.DistributionNotFound: # 都没安装,默认安装CPU版本 return ["tensorflow>=2.0"] setup( name="my_module", version="0.1.0", install_requires=get_tensorflow_dep(), # 其他配置项... )
这里要提醒一下:这种动态检测的方式在构建发布用的wheel包时可能会有问题,因为检测是在构建wheel的环境中执行的,而不是用户安装时的环境。如果你需要发布wheel包,建议优先用方案1。
给TensorFlow用户的小提示
顺便提一句:从TensorFlow 2.0版本开始,标准的tensorflow包已经自动包含GPU支持了,不需要再单独安装tensorflow-gpu。如果你的模块支持TensorFlow 2.0及以上版本,其实可以直接依赖"tensorflow>=2.0",TensorFlow会自动检测用户环境中的GPU并使用,这样就能省去区分CPU/GPU版本的麻烦啦。
内容的提问来源于stack exchange,提问作者Honeybear

