小能豆

Python 许多依赖项中的任何一个

py

有时我会遇到这样的情况:我有一个包可以依赖于包 A 或包 B。

例如,我的项目依赖于一个名为的包spam,如果将该项目重命名为pyspam,则我的项目可以依赖于spampyspam

我无法弄清楚(或找不到)如何在 setup.py 中定义此类依赖项。解决这个问题的常用方法是什么?

编辑:我想在中定义依赖项setup.py。类似这样的事情:

from setuptools import setup

setup(
    name='myproject',
    install_requires=[
        'spam || pyspam'
    ]
)

阅读 19

收藏
2024-11-12

共1个答案

小能豆

setup.py 中定义这种“任意其一”类型的依赖项并不完全受到官方支持,因此需要一些变通方法。通常有以下几种方法可以实现此目的:

方法 1:使用 extras_require 实现选择性依赖

一种常见的解决方案是使用 extras_require 字段来定义额外的依赖项。这样,用户可以根据需要选择安装 spampyspam

from setuptools import setup

setup(
    name='myproject',
    install_requires=[
        # 默认的依赖项(如果没有默认项,可为空)
    ],
    extras_require={
        'spam': ['spam'],
        'pyspam': ['pyspam'],
    },
)

在这种情况下,用户可以选择在安装时指定额外的依赖项,例如:

pip install myproject[spam]

pip install myproject[pyspam]

这样可以给用户提供选择的机会。

方法 2:在 setup.py 中动态检查依赖项

另一种方法是使用 try-exceptsetup.py 中检查 spampyspam 是否已经安装,动态设置 install_requires

from setuptools import setup

try:
    import spam
    required_package = 'spam'
except ImportError:
    required_package = 'pyspam'

setup(
    name='myproject',
    install_requires=[required_package],
)

这个方法会在安装时检查是否已安装 spam,如果没有,则会将 pyspam 设置为依赖项。但请注意,这样的动态依赖在复杂环境下可能会产生不可预见的问题。

方法 3:在文档中说明依赖项选择

如果上述方法不符合项目需求,另一种方法是将依赖项的选择留给用户,即不在 setup.py 中定义可选依赖项,而是在项目文档中说明用户可以安装 spampyspam,例如:

# 安装说明

该项目依赖 `spam` 或 `pyspam` 包。请根据需要选择安装其中之一:

```bash
pip install spam
# 或者
pip install pyspam

```

这样做可以最大限度地保持 setup.py 的简单性,但依赖项的安装步骤需要用户手动执行。

方法 4:使用 pkg_resources 在运行时进行导入检查

对于更复杂的依赖关系,可以考虑在运行时使用 pkg_resources 进行依赖项检查。

2024-11-12