如何使用 pip 升级所有 Python 软件包?

是否可以通过pip一次升级所有 Python 软件包?

注意 :官方问题追踪器上对此功能有要求

答案

还没有内置标志,但是您可以使用

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将跳过 @jawache 建议的可编辑(“-e”)软件包定义。 (是的,您可以将grep + cut替换为sedawkperl或...)。

如果更新一个软件包失败(感谢@andsens ),则xargs-n1标志可阻止停止所有操作。

您可以使用以下 Python 代码。与pip freeze不同,这不会打印警告和 FIXME 错误。 对于点 < 10.0.1

import pip
from subprocess import call

packages = [dist.project_name for dist in pip.get_installed_distributions()]
call("pip install --upgrade " + ' '.join(packages), shell=True)

对于点 > = 10.0.1

import pkg_resources
from subprocess import call

packages = [dist.project_name for dist in pkg_resources.working_set]
call("pip install --upgrade " + ' '.join(packages), shell=True)

升级所有本地软件包;您可以使用pip-review

$ pip install pip-review
$ pip-review --local --interactive

pip-reviewpip-tools一个分支。请参阅@knedlsepp提到的pip-tools问题pip-review软件包有效,但pip-tools软件包不再有效。

从 0.5 版开始, pip-review在 Windows 上运行。

适用于 Windows。也应该对别人有好处。 ($ 是您在命令提示符下所在的目录,例如 C:/ Users / Username>)

$ pip freeze > requirements.txt

打开文本文件,将==替换为>= ,然后执行

$ pip install -r requirements.txt --upgrade

如果您对某个软件包停止升级有问题(有时为 numpy),只需转到目录($),注释掉名称(在其前面添加#),然后再次运行升级。您稍后可以取消对该部分的注释。这对于复制 python 全局环境也非常有用。


另一种方式:

我也喜欢 pip-review 方法:

py2
$ pip install pip-review

$ pip-review --local --interactive

py3
$ pip3 install pip-review

$ py -3 -m pip_review --local --interactive

您可以选择 “a” 来升级所有软件包。如果一次升级失败,请再次运行它,然后继续进行下一次升级。

Windows 版本,查阅了 Rob 的出色的FOR 文档之后

for /F "delims===" %i in ('pip freeze -l') do pip install -U %i

使用pipupgrade

$ pip install pipupgrade
$ pipupgrade --latest --yes

pipupgrade可帮助您从requirements.txt文件升级系统,本地或软件包!它还有选择地升级不会破坏更改的软件包。 pipupgrade 还确保升级存在于多个 Python 环境中的软件包。与 Python2.7 +,Python3.4 + 和 pip9 +,pip10 +,pip18 +,pip19 + 兼容。

在此处输入图片说明

注意:我是该工具的作者。

您可以只打印过时的软件包

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

在我看来,这个选项更直接易读:

pip install -U `pip list --outdated | tail -n +3 | awk '{print $1}'`

解释是pip list --outdated以这种格式输出所有过时软件包的列表:

Package   Version Latest Type 
--------- ------- ------ -----
fonttools 3.31.0  3.32.0 wheel
urllib3   1.24    1.24.1 wheel
requests  2.20.0  2.20.1 wheel

tail -n +3跳过前两行,而awk '{print $1}'选择每行的第一个单词。

以下一线可能会有所帮助:

pip list --format freeze --outdated | sed 's/(.*//g' | xargs -n1 pip install -U

如果出现错误, xargs -n1继续运行。

如果您需要对遗漏的内容和引起错误的内容进行更多的 “细粒度” 控制,则不应添加-n1标志并显式定义要忽略的错误,方法是为每个单独的错误 “插入” 以下行:

| sed 's/^<First characters of the error>.*//'

这是一个工作示例:

pip list --format freeze --outdated | sed 's/(.*//g' | sed 's/^<First characters of the first error>.*//' | sed 's/^<First characters of the second error>.*//' | xargs pip install -U

更强大的解决方案

对于 pip3,请使用以下命令:

pip3 freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip3 install -U \1/p' |sh

对于点子,只需将 3 删除即可:

pip freeze --local |sed -rn 's/^([^=# \t\\][^ \t=]*)=.*/echo; echo Processing \1 ...; pip install -U \1/p' |sh

OSX 奇数

截至 2017 年 7 月,OSX 随附了非常老版本的 sed(已有十二年历史)。要获取扩展的正则表达式,请在上述解决方案中使用 - E 而不是 - r。

用流行的解决方案解决问题

该解决方案经过精心设计和测试1 ,而即使是最流行的解决方案也存在问题。

  • 由于更改 pip 命令行功能而导致的可移植性问题
  • 由于常见的 pip 或 pip3 子进程失败而导致 xargs 崩溃
  • 来自原始 xargs 输出的拥挤日志
  • 依靠 Python 到 OS 的网桥,同时可能对其进行升级3

上面的命令结合使用 sed 和 sh 来使用最简单,最可移植的 pip 语法来完全解决这些问题。 sed 操作的详细信息可以通过注释的版本2进行审查。


细节

[1] 经过测试,并在 Linux 4.8.16-200.fc24.x86_64 群集中正常使用,并在其他五种 Linux / Unix 版本上进行了测试。它还可以在 Windows 10 上安装的 Cygwin64 上运行。需要在 iOS 上进行测试。

[2] 为了更清楚地了解命令的结构,这与上面带有注释的 pip3 命令完全等效:

# match lines from pip's local package list output
# that meet the following three criteria and pass the
# package name to the replacement string in group 1.
# (a) Do not start with invalid characters
# (b) Follow the rule of no white space in the package names
# (c) Immediately follow the package name with an equal sign
sed="s/^([^=# \t\\][^ \t=]*)=.*"

# separate the output of package upgrades with a blank line
sed="$sed/echo"

# indicate what package is being processed
sed="$sed; echo Processing \1 ..."

# perform the upgrade using just the valid package name
sed="$sed; pip3 install -U \1"

# output the commands
sed="$sed/p"

# stream edit the list as above
# and pass the commands to a shell
pip3 freeze --local |sed -rn "$sed" |sh

[3] 升级还用于升级 Python 或 PIP 组件的 Python 或 PIP 组件可能是导致死锁或软件包数据库损坏的潜在原因。