是否可以使用pip一次性升级所有Python包?

注意:官方问题跟踪器上对此有一个功能请求。


当前回答

改用pipx:

pipx upgrade-all

其他回答

您可以只打印过期的软件包:

pip freeze | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'

还没有内置标志。从pip版本22.3开始,--过时和--format=freeze变得互斥。使用Python解析json输出:

pip --disable-pip-version-check list --outdated --format=json | python -c "import json, sys; print('\n'.join([x['name'] for x in json.load(sys.stdin)]))"

如果您正在使用pip<22.3,则可以使用:

pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

对于旧版本的pip:

pip freeze --local | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

grep是跳过可编辑(“-e”)包定义,正如@jawache所建议的那样。(是的,您可以用sed、awk、perl或…替换grep+cut)。xargs的-n1标志防止在更新一个包失败时停止所有操作(谢谢@andss)。


注意:这有无限的潜在变化。我试图让这个答案简短明了,但请在评论中提出建议!

这里有一个脚本,它只更新过时的包。

import os, sys
from subprocess import check_output, call

file = check_output(["pip.exe",  "list", "--outdated", "--format=legacy"])
line = str(file).split()

for distro in line[::6]:
    call("pip install --upgrade " + distro, shell=True)

对于不输出为传统格式的新版本pip(版本18+):

import os, sys
from subprocess import check_output, call

file = check_output(["pip.exe", "list", "-o", "--format=json"])
line = str(file).split()

for distro in line[1::8]:
    distro = str(distro).strip('"\",')
    call("pip install --upgrade " + distro, shell=True)

Windows PowerShell解决方案

pip freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_}

如果您希望升级仅由pip安装,并且避免升级由其他工具(如apt、yum等)安装的软件包,那么您可以使用我在Ubuntu上使用的脚本(可能也适用于其他发行版)-基于以下帖子:

printf "To update with pip: pip install -U"
pip list --outdated 2>/dev/null | gawk '{print $1;}' | while read; do pip show "${REPLY}" 2>/dev/null | grep 'Location: /usr/local/lib/python2.7/dist-packages' >/dev/null; if (( $? == 0 )); then printf " ${REPLY}"; fi; done; echo