一些 Python 包需要两个包之一作为依赖项。例如,Ghost.py
需要PySide
或PyQt4
。
是否可以在文件中包含这样的依赖关系requirements.txt
?是否有任何“或”运算符适用于这些文件?
如果没有,我该怎么做才能将这些要求添加到文件中,以便只安装其中一个?
一些 Python 包需要两个包之一作为依赖项。例如,Ghost.py
需要PySide
或PyQt4
。
是否可以在文件中包含这样的依赖关系requirements.txt
?是否有任何“或”运算符适用于这些文件?
如果没有,我该怎么做才能将这些要求添加到文件中,以便只安装其中一个?
目前,piprequirement.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
。最后,您必须问自己为什么人们可能想要使用一个依赖项而不是另一个:我通常不太关心我使用的库的依赖项,因为(磁盘)空间很便宜并且(由于 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 ...