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

问题描述 投票:0回答:13

我正在安装来自

requirements.txt

的软件包
pip install -r requirements.txt

requirements.txt
文件内容如下:

Pillow
lxml
cssselect
jieba
beautifulsoup
nltk

lxml
是唯一无法安装的软件包,这会导致一切失败(larsks 在评论中指出的预期结果)。然而,在
lxml
失败后,
pip
仍然运行并下载其余的包。

据我了解,如果

pip install -r requirements.txt
中列出的任何软件包无法安装,
requirements.txt
命令将失败。

在运行

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

python pip
13个回答
469
投票

使用

pip install
运行每一行可能是一种解决方法。

cat requirements.txt | xargs -n 1 pip install

注意:

-a
参数在MacOS下不可用,所以老猫更便携。


37
投票

此解决方案可处理您的requirements.txt中的空行、空白行、#注释行、空白-然后-#注释行。

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

向这个 sed 魔法的answer致敬。


18
投票

对于Windows用户,您可以使用这个:

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

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


12
投票

对于 Windows:

点版本>=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

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)

7
投票

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

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

6
投票

一行 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 $_}}


4
投票

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

3
投票

对于使用 PowerShell 的 Windows:

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

3
投票

另一种选择是使用

pip install --dry-run
获取需要安装的软件包列表,然后继续尝试并删除不起作用的软件包。


2
投票

一个非常通用的解决方案

以下代码安装了以下所有要求:

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

1
投票

谢谢 Etienne Prothon 提供的窗户案例。

但是,升级到 pip 18 后,pip 包不会将 main 公开给公众。所以你可能需要像这样更改代码。

 # 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)

0
投票

Windows Powershell,忽略所有注释,即使注释位于库名称之后:

Get-Content requirements.txt | ForEach-Object {if (!$_.startswith("#")){$x = $_ -replace '#.+',''; pip install $x}}

这支持这样的需求文件:

Pillow
lxml # an in-line comment
cssselect
# a comment line
jieba
beautifulsoup
nltk

-2
投票

对于 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'])

© www.soinside.com 2019 - 2024. All rights reserved.