当使用requirements.txt安装时,防止pip在单个包上失败

我正在从requirements.txt安装包

pip install -r requirements.txt

requirements.txt文件如下:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

lxml是唯一一个安装失败的包,这会导致所有的失败(正如larsks在评论中指出的那样,预期的结果)。然而,在lxml失败后,pip仍然运行并下载其余的包。

根据我的理解,如果requirements.txt中列出的任何包未能安装,pip install -r requirements.txt命令将失败。

在运行pip install -r requirements.txt时,是否有任何参数可以传递给它,以告诉它安装它可以安装的包,并跳过它不能安装的包,或者在它看到某些失败时立即退出?

125590 次浏览

使用pip install运行每一行可能是一种变通方法。

cat requirements.txt | xargs -n 1 pip install

注意:-a参数在MacOS下不可用,所以old cat更便于移植。

xargs解决方案可以工作,但可能有可移植性问题(BSD/GNU)和/或如果您的需求文件中有注释或空行,则会很麻烦。

至于需要这种行为的用例,我使用了两个单独的需求文件,一个只列出了需要始终安装的核心依赖项,另一个文件列出了在90%的情况下对大多数用例不需要的非核心依赖项。这相当于debian包的Recommends部分。

我使用以下shell脚本(需要sed)来安装可选依赖关系:

#!/bin/sh


while read dependency; do
dependency_stripped="$(echo "${dependency}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
# Skip comments
if [[ $dependency_stripped == \#* ]]; then
continue
# Skip blank lines
elif [ -z "$dependency_stripped" ]; then
continue
else
if pip install "$dependency_stripped"; then
echo "$dependency_stripped is installed"
else
echo "Could not install $dependency_stripped, skipping"
fi
fi
done < recommends.txt

Windows:

PIP版本>=18

import sys
from pip._internal import main as pip_main


def install(package):
pip_main(['install', package])


if __name__ == '__main__':
with open(sys.argv[1]) as f:
for line in f:
install(line)

18 . PIP版本<

import sys
import pip


def install(package):
pip.main(['install', package])


if __name__ == '__main__':
with open(sys.argv[1]) as f:
for line in f:
install(line)

谢谢你,艾蒂安·普罗通。

但是,升级到pip 18后,pip包主要不会向公众公开。因此,您可能需要像这样更改代码。

 # This code install line by line a list of pip package
import sys
from pip._internal import main as pip_main


def install(package):
pip_main(['install', package])


if __name__ == '__main__':
with open(sys.argv[1]) as f:
for line in f:
install(line)

这个解决方案可以处理requirements.txt中的空行、空格行、#注释行、空格-然后-#注释行。

cat requirements.txt | sed -e '/^\s*#.*$/d' -e '/^\s*$/d' | xargs -n 1 pip install

对这个回答的sed魔术致敬。

Windows:

import os
from pip.__main__ import _main as main


error_log = open('error_log.txt', 'w')


def install(package):
try:
main(['install'] + [str(package)])
except Exception as e:
error_log.write(str(e))


if __name__ == '__main__':
f = open('requirements1.txt', 'r')
for line in f:
install(line)
f.close()
error_log.close()
  1. 创建一个本地目录,并将你的requirements.txt文件放在其中。
  2. 复制上面的代码,并将其保存为同一个目录中的python文件。记住使用.py扩展名,例如,install_packages.py
  3. 使用cmd: python install_packages.py运行该文件
  4. 所有提到的包都将一次性安装,完全不会停止。:)

您可以在安装函数中添加其他参数。如: main(['install'] + [str(package)] + ['--update']) < / p >

对于windows用户,你可以使用这个:

FOR /F %k in (requirements.txt) DO ( if NOT # == %k ( pip install %k ) )

逻辑:对于文件(requirements.txt)中的每个依赖项,安装它们并忽略那些以"#"开头的依赖项。

对于使用PowerShell的Windows:

foreach($line in Get-Content requirements.txt) {
if(!($line.StartsWith('#'))){
pip install $line
}
}

一行PowerShell:

Get-Content .\requirements.txt | ForEach-Object {pip install $_}

如果你需要忽略某些行,那么:

Get-Content .\requirements.txt | ForEach-Object {if (!$_.startswith("#")){pip install $_}}

Get-Content .\requirements.txt | ForEach-Object {if ($_ -notmatch "#"){pip install $_}}

基于@MZD的回答,这里有一个解决方案,可以过滤掉所有以注释符号#开头的文本

cat requirements.txt | grep -Eo '(^[^#]+)' | xargs -n 1 pip install

另一种选择是使用pip install --dry-run来获取你需要安装的包的列表,然后继续尝试并删除那些不工作的包。

一个非常一般的解

下面的代码安装所有的需求:

  • 多个需求文件(requirements1.txtrequirements2.txt)
  • 忽略带有注释#的行
  • 跳过不可安装的包
  • 运行pip install each line(不是像其他答案中的每个单词)
$ (cat requirements1.txt; echo ""; cat requirements2.txt) | grep "^[^#]" | xargs -L 1 pip install