只需要需求文件中的两个依赖项之一
Requiring only one of two dependencies in a requirements file
一些 Python 包需要两个包之一作为依赖项。例如,Ghost.py
需要 PySide
或 PyQt4
。
是否可以在 requirements.txt
文件中包含这样的依赖项?是否有任何 'or' 运算符可以处理这些文件?
如果没有,我该怎么做才能将这些要求添加到文件中以便只安装其中一个?
目前 pip 的 requirement.txt
和 setuptools 都不直接允许这样的构造。两者都要求您指定一个要求列表。您可以限制需求的版本,仅此而已。
在Python里面,你可以这样处理这种情况:
try:
import dependency1
def do_it(x):
return dependency1.some_function(x)
except ImportError:
try:
import dependency2
def do_it(x)
return dependency2.another_function(x)
except ImportError:
raise ImportError('You must install either dependency1 or '
+ 'dependecy2!')
现在 do_it
使用 dependency1.some_function
或 dependency2.another_function
,具体取决于哪个可用。
这仍然会给您留下如何指定您的要求的问题。我看到两个选项:
- 不要在
requirements.txt
或 setup.py
中正式指定要求,但要记录用户需要安装其中一个依赖项。如果您的软件设置无论如何都需要额外的手动步骤(即不仅仅是 pip install my_tool
),那么这种方法可能没问题。
- 在
requirements.txt
或 setup.py
中硬编码您的首选要求。
最后,你必须问问自己为什么人们可能想要使用一个依赖项而不是另一个依赖项:我通常不太关心我使用的库的依赖项,因为 (disk) space 很便宜并且(由于 virtualenv)不兼容的风险很小。因此,我什至建议您考虑不为相同的功能支持两种不同的依赖项。
我会使用一个小的 Python 脚本来完成这个
#!/usr/bin/env python
packages = 'p1 p2 p3'.split()
try:
import optional1
except ImportError: # opt1 not installed
try:
import optional2
except ImportError: # opt2 not installed
packages.append('optional2')
print(' '.join(packages))
让此脚本可执行
chmod +x requirements.py
最后 运行 pip 是这样的:
pip install $(requirements.py)
'$(requirements.py)' 将执行 requirements.py 脚本并将其输出(在本例中为软件包列表)放入 pip install ...
对于 setuptools,您可以将 setup
代码更改为类似于此处:
https://github.com/albumentations-team/albumentations/blob/master/setup.py#L11
如果 dependency1
和 dependency2
中的 none 已经安装,则 dependency1
将被安装,但如果其中任何一个已经是系统的一部分,则不会安装任何内容.
需要注意的是它不适用于轮子,您需要安装 --no-binary
才能使其工作:https://albumentations.ai/docs/getting_started/installation/#note-on-opencv-dependencies
一些 Python 包需要两个包之一作为依赖项。例如,Ghost.py
需要 PySide
或 PyQt4
。
是否可以在 requirements.txt
文件中包含这样的依赖项?是否有任何 'or' 运算符可以处理这些文件?
如果没有,我该怎么做才能将这些要求添加到文件中以便只安装其中一个?
目前 pip 的 requirement.txt
和 setuptools 都不直接允许这样的构造。两者都要求您指定一个要求列表。您可以限制需求的版本,仅此而已。
在Python里面,你可以这样处理这种情况:
try:
import dependency1
def do_it(x):
return dependency1.some_function(x)
except ImportError:
try:
import dependency2
def do_it(x)
return dependency2.another_function(x)
except ImportError:
raise ImportError('You must install either dependency1 or '
+ 'dependecy2!')
现在 do_it
使用 dependency1.some_function
或 dependency2.another_function
,具体取决于哪个可用。
这仍然会给您留下如何指定您的要求的问题。我看到两个选项:
- 不要在
requirements.txt
或setup.py
中正式指定要求,但要记录用户需要安装其中一个依赖项。如果您的软件设置无论如何都需要额外的手动步骤(即不仅仅是pip install my_tool
),那么这种方法可能没问题。 - 在
requirements.txt
或setup.py
中硬编码您的首选要求。
最后,你必须问问自己为什么人们可能想要使用一个依赖项而不是另一个依赖项:我通常不太关心我使用的库的依赖项,因为 (disk) space 很便宜并且(由于 virtualenv)不兼容的风险很小。因此,我什至建议您考虑不为相同的功能支持两种不同的依赖项。
我会使用一个小的 Python 脚本来完成这个
#!/usr/bin/env python
packages = 'p1 p2 p3'.split()
try:
import optional1
except ImportError: # opt1 not installed
try:
import optional2
except ImportError: # opt2 not installed
packages.append('optional2')
print(' '.join(packages))
让此脚本可执行
chmod +x requirements.py
最后 运行 pip 是这样的:
pip install $(requirements.py)
'$(requirements.py)' 将执行 requirements.py 脚本并将其输出(在本例中为软件包列表)放入 pip install ...
对于 setuptools,您可以将 setup
代码更改为类似于此处:
https://github.com/albumentations-team/albumentations/blob/master/setup.py#L11
如果 dependency1
和 dependency2
中的 none 已经安装,则 dependency1
将被安装,但如果其中任何一个已经是系统的一部分,则不会安装任何内容.
需要注意的是它不适用于轮子,您需要安装 --no-binary
才能使其工作:https://albumentations.ai/docs/getting_started/installation/#note-on-opencv-dependencies