ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 pip 升级所有 Python 包

想要改进这篇文章?提供这个问题的详细答案,包括引文和解释为什么你的答案是正确的。没有足够细节的答案可能会被编辑或删除。

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

注意:官方问题跟踪器上有 a feature request

当心 software rot — 升级依赖项可能会破坏您的应用程序。您可以使用 pip freeze(如 bundle installnpm shrinkwrap)列出所有已安装软件包的确切版本。最好在修补之前保存一份副本。
如果您想更新单个包及其所有依赖项(可以说是一种更明智的方法),请执行以下操作: pip install -U --upgrade-strategy eager your-package
我使用 PowerShell 7,目前我使用这个单行:pip list --format freeze | %{pip install --upgrade $_.split('==')[0]}(我还无法在此处发布答案)

M
Mateen Ulhaq

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

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

正如@jawache 所建议的,grep 将跳过可编辑(“-e”)包定义。 (是的,您可以将 grep+cut 替换为 sed 或 awk 或 perl 或...)。

如果更新一个包失败, xargs 的 -n1 标志可以防止停止一切(感谢@andsens)。

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


对 :( 问题现在存在于 github.com/pypa/pip/issues/59 。但似乎每个建议都以“是的,但我太确定 X 是否是做 Y 的正确方法”......现在总比没有好?实用性胜过纯度?:(
它还会打印那些使用普通包管理器(如 apt-get 或 Synaptic)安装的包。如果我执行此 pip install -U,它将更新所有包。恐怕它会导致与 apt-get 发生冲突。
将 grep 更改为: egrep -v '^(\-e|#)' 怎么样(我在 ubuntu 12.10 上运行它时得到这一行:“## FIXME: could not find svn URL in dependency_links for this package:”。
在进行实际升级之前,我会添加一个 tee,以便您可以获得原始版本的列表。例如 pip freeze --local | tee before_upgrade.txt | ... 这样如果有任何问题,它会更容易恢复。
我将 -H 添加到 sudo 以避免出现烦人的错误消息:$ pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 sudo -H pip install -U
M
MSS

您可以使用以下 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)

这工作得非常好……当一项任务需要很长时间时,它总是那么令人满意……并给你一堆新东西! PS:如果您在 OS X 上,请以 root 身份运行!
有没有办法在不调用子进程的情况下使用 pip 安装? import pip pip.install('packagename') 之类的东西?
我将其包装在 fabfile.py 中。谢谢!
@BenMezger:你真的不应该在你的 virtualenv 中使用系统包。你也真的不应该以 root 身份运行多个受信任的、知名的程序。使用 --no-site-packages 运行您的 virtualenvs(最新版本中的默认设置)。
对此竖起大拇指,如果再也找不到包,则选择的答案(上图)将失败。这个脚本简单地继续下一个包,太棒了。
P
Pikamander2

要升级所有本地软件包,您可以安装 pip-review

$ pip install pip-review

之后,您可以交互升级软件包:

$ pip-review --local --interactive

或自动:

$ pip-review --local --auto

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

pip-review 适用于 Windows since version 0.5


@hauzer:它不支持 Python 3。虽然 it might be a bug
@mkoistinen 这是一个很好的工具,但在它被合并到 PIP 之前,它意味着安装一些不是每个人都可能想要做的额外的东西。
@Daniel:pip-tools 不再有效,pip-review(pip-tools 的分支)有效。
pip-review 工作得很好(至少对于 Python 3.5.0 版)
要在没有交互模式的情况下全部更新:pip-review --local --auto
a
azazelspeaks

以下内容适用于 Windows,对其他人也应该有用($ 是您所在的目录,在命令提示符中。例如,C:/Users/Username)。

$ pip freeze > requirements.txt

打开文本文件,将 == 替换为 >=,或者让 sed 为您完成:

$ sed -i 's/==/>=/g' 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”来升级所有软件包;如果一次升级失败,请再次运行它并在下一次继续。


您应该删除 requirements.txt=={version}。例如:所有行的 python-dateutil==2.4.2python-dateutil
我发现这实际上并没有升级 macOS 上的软件包。
@youngminz 在运行“pip install ...”之前,我会建议在您的编辑器/ide 中快速“替换所有“==”>“>=”来解决此问题
对于 linux:$ pip freeze | cut -d '=' -f1> requirements.txt 以删除版本
如果您使用的 shell 是 bash,您可以通过 pip3 install -r <(pip3 freeze) --upgrade 将其缩短为一个命令 实际上,<(pip3 freeze) 是一个匿名管道,但它将充当文件对象
P
Peter Mortensen

使用 pip 升级!

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

pipupgrade 可帮助您从 requirements.txt 文件升级系统、本地或软件包!它还选择性地升级不会破坏更改的软件包。

pipupgrade 还确保升级存在于多个 Python 环境中的包。它与 Python 2.7+、Python 3.4+ 和 pip 9+、pip 10+、pip 18+、pip 19+ 兼容。

https://i.stack.imgur.com/37F74.gif

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


这种方法的输出比@rbp 的答案要干净得多
好主意,但是当我尝试它时它永远停留在 Checking...
在 Windows 10 和 Python 3.7.5 上出现错误:ModuleNotFoundError: No module named 'ctypes.windll'
似乎有一些问题:Checking... 2020-03-16 11:37:03,587 | WARNING | Unable to save package name. UNIQUE constraint failed: tabPackage.name 2020-03-16 11:37:13,604 | WARNING | Unable to save package name. database is locked 2020-03-16 11:37:13,609 | WARNING | Unable to save package name. database is locked
似乎这会将所有软件包升级到最新版本,这可能会破坏一些依赖关系。
w
wilson

参考 Rob van der Woude 的优秀 documentation for FOR 后的 Windows 版本:

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

for /F "delims= " %i in ('pip list --outdated') do pip install -U %i 更快,因为它只会尝试更新“过时”的软件包
@RefaelAckermann 我怀疑这会比原来的要慢:) 要知道哪些包已过时,pip 必须首先检查每个包的最新版本。它与更新时的第一步完全相同,如果没有可用的更新版本,则不会继续。但是,在您的版本中,pip 会检查两次版本,第一次是建立过时软件包列表,第二次是在更新此列表中的软件包时。
@RefaelAckermann 启动 pip 比通过网络检查包的版本要快一个数量级,因此应该优化的检查次数而不是启动次数。我的进行 n 次检查,你的进行 n+m 次检查。
+1 - 现在是 6.20.2019,我在 WIndows 10 上使用 Python 3.7.3,这是我更新所有本地包的最佳方式。
需要跳过输出的前两行:for /F "skip=2 delims= " %i in ('pip list --outdated') do pip install --upgrade %i。如果这是从批处理文件运行的,请确保使用 %%i 而不是 %i。另请注意,在使用 python -m pip install --upgrade pip 运行此命令之前更新 pip 会更简洁。
M
Marc

这个选项在我看来更直接和可读:

pip install -U `pip list --outdated | awk 'NR>2 {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

在 awk 命令中,NR>2 跳过前两条记录(行),{print $1} 选择每行的第一个单词(正如 SergioAraujo 所建议的,我删除了 tail -n +3,因为 awk 确实可以处理跳过记录)。


如果一次升级失败,则不会发生任何升级。
r
raratiru

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

(点 > 20.0)

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

旧版本: 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

必须为以 'Could' 和 'Some' 开头的行添加过滤器,因为显然 pip 向标准输出发送警告:(
好的,这很公平:您可以根据需要添加任意数量的 | sed 's/^<First characters of the error>.*//'。谢谢!
或者:pip list --outdated | cut -d ' ' -f 1 | xargs -n 1 pip install --upgrade
P
Peter Mortensen

您可以只打印过时的包:

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

在 virtualenv 中,我这样做:pip freeze --local | cut -d = -f 1 | xargs -n 1 pip search | grep -B2 'LATEST:'
现在,您也可以使用 python -m pip list outdated 来做到这一点(尽管它不是要求格式)。
@Jacktose 我认为您的意思是python -m pip list --outdated
M
Michel

更强大的解决方案

对于 pip3,使用这个:

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

对于 pip,只需像这样删除 3s:

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

OS X 古怪

截至 2017 年 7 月,OS X 附带了一个非常旧的 sed 版本(十几年前)。要获得扩展的正则表达式,请在上述解决方案中使用 -E 而不是 -r

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

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

由于更改 pip 命令行功能而导致的可移植性问题

由于常见的 pip 或 pip3 子进程失败导致 xargs 崩溃

来自原始 xargs 输出的拥挤日志记录

依赖 Python 到 OS 的桥,同时可能升级它3

上面的命令使用最简单和最便携的 pip 语法结合 sed 和 sh 来完全克服这些问题。 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 组件可能是导致死锁或包数据库损坏的潜在原因。


克服 OS X 侏罗纪 BSD sed 的另一种方法是改用 gsed (GNU sed)。要获得它,brew install gnu-sed
@WalterTross ...侏罗纪...很好的形容词使用。因此,我们现在有两种方法可以在终端上通过良好的审计跟踪对更新 pip 包进行分组。 (1)使用答案中的 -E 选项和(2)安装 gsed 以离开侏罗纪时期。
P
Peter Mortensen

我在升级时遇到了同样的问题。问题是,我从不升级所有软件包。我只升级我需要的东西,因为项目可能会中断。

因为没有简单的方法来逐个升级包并更新 requirements.txt 文件,所以我编写了这个pip-upgrader,它还更新了您的 requirements.txt 文件中所选包(或所有软件包)。

安装

pip install pip-upgrader

用法

激活您的 virtualenv(很重要,因为它还会在当前 virtualenv 中安装新版本的升级包)。

cd 进入您的项目目录,然后运行:

pip-upgrade

高级用法

如果需求放置在非标准位置,请将它们作为参数发送:

pip-upgrade path/to/requirements.txt

如果您已经知道要升级的软件包,只需将它们作为参数发送:

pip-upgrade -p django -p celery -p dateutil

如果您需要升级到预发布/发布后版本,请在命令中添加 --prerelease 参数。

完全披露:我写了这个包。


这是 pip 默认应该做的。
使用您的工具,某些字符转义似乎在我的 Windows 机器上无法正常工作,但除此之外它很好
还没有在windows上真正测试过,但我会安装一个虚拟机。谢谢
如果 virtualenv 未启用 pip-upgrade --skip-virtualenv-check
这也适用于具有 common、dev 和 prod 要求的要求文件夹。简直太棒了!
S
Shihao Xu

这似乎更简洁。

pip list --outdated | cut -d ' ' -f1 | xargs -n1 pip install -U

解释:

pip list --outdated 得到这样的行

urllib3 (1.7.1) - Latest: 1.15.1 [wheel]
wheel (0.24.0) - Latest: 0.29.0 [wheel]

cut -d ' ' -f1中,-d ' '设置“空格”作为分隔符,-f1表示获取第一列。

所以上面的行变成:

urllib3
wheel

然后将它们传递给 xargs 以运行命令 pip install -U,每行作为附加参数

-n1 将传递给每个命令 pip install -U 的参数数量限制为 1


我收到此警告 DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
@Reman:那是因为您使用的是 Pip v9.0.1。这只是一条弃用消息,意味着某些功能在未来的 Pip 版本中将无法生存。没什么好担心的;)
但是,这必须标记为最终解决方案。实际上,接受的答案将在您的 pip 包中运行,如果您只需要更新 1 或 2 个包,这是浪费时间。相反,此解决方案将在所有过时的软件包中运行
P
Peter Mortensen

Ramana's answer 的单行版本。

python -c 'import pip, subprocess; [subprocess.call("pip install -U " + d.project_name, shell=1) for d in pip.get_installed_distributions()]'

subprocess.call("sudo pip install... 如果您需要权限
@MaximilianoRios 请不要使用 sudo pip install,而是使用 virtual env
P
Peter Mortensen

来自 https://github.com/cakebread/yolk

$ pip install -U `yolk -U | awk '{print $1}' | uniq`

但是,你需要先得到蛋黄:

$ sudo pip install -U yolk

最后一次提交 7 年前
P
Peter Mortensen

使用 virtualenv 时,如果您只想将 添加 的软件包升级到您的 virtualenv,您可能需要执行以下操作:

pip install `pip freeze -l | cut --fields=1 -d = -` --upgrade

A
Andrew Jaffe

pip_upgrade_outdated(基于 this older script)完成这项工作。根据its documentation

usage: pip_upgrade_outdated [-h] [-3 | -2 | --pip_cmd PIP_CMD]
                            [--serial | --parallel] [--dry_run] [--verbose]
                            [--version]

Upgrade outdated python packages with pip.

optional arguments:
  -h, --help         show this help message and exit
  -3                 use pip3
  -2                 use pip2
  --pip_cmd PIP_CMD  use PIP_CMD (default pip)
  --serial, -s       upgrade in serial (default)
  --parallel, -p     upgrade in parallel
  --dry_run, -n      get list, but don't upgrade
  --verbose, -v      may be specified multiple times
  --version          show program's version number and exit

步骤1:

pip install pip-upgrade-outdated

第2步:

pip_upgrade_outdated

第 1 步:pip install pip-upgrade-outdated 第 2 步:pip-upgrade-outdated ...完成
这确实是一个非常好的包。需要更多宣传,我已经在 python 中工作了很长时间,这是我第一次听说它。好的!
@MarioChapa 谢谢-我写了它(基于要点)。
在 Windows 中,%USERPROFILE%\anaconda3\envs\bridge\scripts\pip_upgrade_outdated.exe
R
RedEyed

我在 pip issue discussion 中找到的最简单、最快的解决方案是:

pip install pipdate
pipdate

来源:https://github.com/pypa/pip/issues/3819


虽然其他解决方案在遇到最轻微的异常时会停止,但此解决方案会发出警告,然后跳过问题继续处理其他包。伟大的!
投票赞成,在 Windows 中完美运行
我使用了 pipdate,现在找不到 pip 或 python。使用风险自负。
P
Peter Mortensen

Windows PowerShell 解决方案

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

pip list --outdated | %{$_.split('==')[0]} | %{pip install --upgrade $_}
也许 pip list --outdated --format freeze | %{$_.split('==')[0]} | %{pip install --upgrade $_} 会更合适。
为什么 pip list --outdated --format freeze.. 比 Powershell 中的建议答案更受欢迎,@brainplot
@Timo 当我写该评论时,建议的答案仅使用 pip list 而不是 pip freeze。我认为 --format freeze 会比让 pip list 决定格式更能抵御未来更新中可能发生的变化。 pip freeze 也有效!
将其作为您的个人资料中的功能更好!这对于任何使用 powershell 的人来说都是完美的
P
Peter Mortensen

使用 AWK 更新包:

pip install -U $(pip freeze | awk -F'[=]' '{print $1}')

Windows PowerShell 更新

foreach($p in $(pip freeze)){ pip install -U $p.Split("=")[0]}

而对于 python 3... pip3 install -U $(pip3 freeze | awk -F'[=]' '{print $1}')
I
Isaque Elcio

在 Windows 或 Linux 上更新 Python 包

1-将已安装软件包的列表输出到需求文件(requirements.txt)中:

pip freeze > requirements.txt

2- 编辑 requirements.txt,并将所有 '==' 替换为 '>='。使用编辑器中的“全部替换”命令。

3 - 升级所有过时的软件包

pip install -r requirements.txt --upgrade

来源:https://www.activestate.com/resources/quick-reads/how-to-update-all-python-packages/


这行得通。之后只需执行 pip freeze > requirements.txt 即可查看实际差异。
pip freeze | sed 's/==/>=/' > requirements.txt 自动将 ==>= 交换。
P
Peter Mortensen

PowerShell 5.1 中的一行具有管理员权限、Python 3.6.5 和 pip 版本 10.0.1:

pip list -o --format json | ConvertFrom-Json | foreach {pip install $_.name -U --no-warn-script-location}

如果列表中没有破损的包裹或特殊的轮子,它可以顺利运行...


出于纯粹的审美原因,我最喜欢这种方法。产生输出的可执行文件为我们的 shell 提供对象模式,并且脚本中不需要未标记的索引值 [0]
G
German Lashevich

用于实现这一目标的纯 Bash/Z shell 单行代码:

for p in $(pip list -o --format freeze); do pip install -U ${p%%=*}; done

或者,以一种格式良好的方式:

for p in $(pip list -o --format freeze)
do
    pip install -U ${p%%=*}
done

代表什么?
@ᐅdevrimbaris 这将删除版本规范并仅保留包名称。您可以通过运行 for p in $(pip list -o --format freeze); do echo "${p} -> ${p%%=*}"; done 来查看它。更一般地说,${haystack%%needle} 表示 delete longest match of needle from back of haystack
P
Peter Mortensen

你可以试试这个:

for i in ` pip list | awk -F ' ' '{print $1}'`; do pip install --upgrade $i; done

这是以最简洁的方式更新 pip 包的最简洁、可读性最高的方法。伟大的。
P
Peter Mortensen

相当神奇的蛋黄使这很容易。

pip install yolk3k # Don't install `yolk`, see https://github.com/cakebread/yolk/issues/35
yolk --upgrade

有关蛋黄的更多信息:https://pypi.python.org/pypi/yolk/0.4.3

它可以做很多你可能会觉得有用的事情。


P
Peter Mortensen

利用:

pip install -r <(pip freeze) --upgrade

P
Peter Mortensen

Ramana's answer 对我来说效果最好,这里的那些,但我必须添加一些问题:

import pip
for dist in pip.get_installed_distributions():
    if 'site-packages' in dist.location:
        try:
            pip.call_subprocess(['pip', 'install', '-U', dist.key])
        except Exception, exc:
            print exc

site-packages 检查排除了我的开发包,因为它们不在系统站点包目录中。 try-except 只是跳过已从 PyPI 中删除的包。

To endolith:我也希望有一个简单的 pip.install(dist.key, upgrade=True),但它看起来不像 pip 旨在用于命令行以外的任何东西(文档没有提到内部 API,pip 开发人员没有使用文档字符串)。


在 Ubuntu(和其他 Debian 衍生产品)上,pip 显然将软件包放在 /usr/local/lib/python2.7/dist-packages 或类似中。在这种情况下,您可以在 if 语句中使用“/usr/local/lib/”而不是“site-packages”。
P
Pang

Windows 上最短和最简单的。

pip freeze > requirements.txt && pip install --upgrade -r requirements.txt && rm requirements.txt

@Enkouyami 在 Windows 7 上此命令在没有 -r 的情况下不起作用。 -r 必须排除需求文件的路径。
在什么情况下?命令? PowerShellCygwinAnaconda?还有什么?
P
Peter Mortensen

通过 a pull-request to the pip folks 发送;同时使用我写的这个 pip 库解决方案:

from pip import get_installed_distributions
from pip.commands import install

install_cmd = install.InstallCommand()

options, args = install_cmd.parse_args([package.project_name
                                        for package in
                                        get_installed_distributions()])

options.upgrade = True
install_cmd.run(options, args)  # Chuck this in a try/except and print as wanted

带错误处理的版本(根据评论):gist.github.com/SamuelMarks/7885f2e8e5f0562b1063
P
Peter Mortensen

这似乎对我有用......

pip install -U $(pip list --outdated | awk '{printf $1" "}')

之后我使用带有空格的 printf 来正确分隔包名称。


C
Cheung

没有必要这么麻烦或安装一些包。

在 Linux shell 上更新 pip 包:

pip list --outdated --format=freeze | awk -F"==" '{print $1}' | xargs -i pip install -U {}

在 Windows powershell 上更新 pip 包:

pip list --outdated --format=freeze | ForEach { pip install -U $_.split("==")[0] }

几点:

将 pip 作为您的 python 版本替换为 pip3 或 pip2。

pip list --outdated 检查过时的 pip 包。

--format 在我的 pip 版本 22.0.3 上只有 3 种类型:列(默认)、冻结或 json。 freeze 是命令管道中更好的选择。

使命令尽可能简单和可用。


感谢您提供 PowerShell 片段,这对我来说是最有用的答案!