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

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

说明:官方问题跟踪器上有一个功能请求

1648067 次浏览

还没有内置标志。从pip版本22.3开始,--outdated--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所建议的那样。(是的,您可以将grep+cut替换为sedawkperl或…)。

  • xargs-n1标志防止在更新一个包失败时停止所有内容(感谢@刘德华)。


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

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

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

对于pip>=10.0.1

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

这是我对rbp的回答的变体,它绕过了“可编辑”和开发发行版。它与原始版本有两个缺陷:它不必要地重新下载和重新安装;一个包上的错误将阻止之后每个包的升级。

pip freeze |sed -ne 's/==.*//p' |xargs pip install -U --

相关bug报道,从Bitucket迁移后有点脱节:

您可以只打印过时的包:

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

使用虚拟环境时,如果您只想将包添加升级到您的虚拟环境,您可能需要执行:

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

Windows版本在查阅Rob van der Woude的优秀留档#0后:

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

https://github.com/cakebread/yolk

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

但是,您需要先获得蛋黄:

$ sudo pip install -U yolk

Ramana的回答对我来说是最好的,在这里,但我不得不添加一些捕获:

import pipfor 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除了简单地跳过已从PyPI中删除的包。

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

要升级所有本地软件包,您可以安装#0

$ pip install pip-review

之后,您可以以交互方式升级包:

$ pip-review --local --interactive

或自动:

$ pip-review --local --auto

pip-reviewpip-tools的分叉。参见@陈志立中提到的#1问题pip-review包有效,但pip-tools包不再有效。#0正在寻找新的维护者。

pip-review适用于Windows自0.5版

Ramana的回答的单行版本。

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

你可以试试这个:

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

通过向pip的人发出拉取请求;发送,同时使用我写的这个pip库解决方案:

from pip import get_installed_distributionsfrom pip.commands import install
install_cmd = install.InstallCommand()
options, args = install_cmd.parse_args([package.project_namefor package inget_installed_distributions()])
options.upgrade = Trueinstall_cmd.run(options, args)  # Chuck this in a try/except and print as wanted

我尝试了拉玛那的法典,我发现在Ubuntu上你必须为每个命令编写sudo。这是我的脚本,它在ubuntu 13.10(Saucy Salamander)上运行良好:

#!/usr/bin/env pythonimport pipfrom subprocess import call
for dist in pip.get_installed_distributions():call("sudo pip install --upgrade " + dist.project_name, shell=True)

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

(pip>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

这应该更有效:

pip3 list -o | grep -v -i warning | cut -f1 -d' ' | tr " " "\n" | awk '{if(NR>=3)print}' | cut -d' ' -f1 | xargs -n1 pip3 install -U
  1. pip list -o列出过期的包;
  2. grep -v -i warningwarning上反转匹配以避免更新时出错
  3. cut -f1 -d1' '返回第一个词-过时包的名称;
  4. tr "\n|\r" " "cut的多行结果转换为单行、空格分隔的列表;
  5. awk '{if(NR>=3)print}'跳过标题行
  6. cut -d' ' -f1获取第一列
  7. xargs -n1 pip install -U从管道左侧获取1个参数,并将其传递给命令以升级包列表。

这个选项在我看来更简单易读:

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 wheelurllib3   1.24    1.24.1 wheelrequests  2.20.0  2.20.1 wheel

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

这似乎为我工作…

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

之后我使用printf和空格来正确分隔包名。

以下内容适用于Windows,也适用于其他人(在命令提示符中,$是您所在的任何目录。例如,C:/用户名)。

$ pip freeze > requirements.txt

打开文本文件,将==替换为>=,或者让ses为您执行:

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

这是在Python中使用脚本的另一种方式:

import pip, tempfile, contextlib
with tempfile.TemporaryFile('w+') as temp:with contextlib.redirect_stdout(temp):pip.main(['list', '-o'])temp.seek(0)for line in temp:pk = line.split()[0]print('--> updating', pk, '<--')pip.main(['install', '-U', pk])

相当惊人的蛋黄使这变得容易。

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

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

它可以做很多你可能会发现有用的事情。

这似乎更简洁。

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表示获取第一列。

所以上面的线变成了:

urllib3wheel

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

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

Windows PowerShell解决方案

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

这是一个仅更新过时包的脚本。

import os, sysfrom 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, sysfrom 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)

用途:

import pippkgs = [p.key for p in pip.get_installed_distributions()]for pkg in pkgs:pip.main(['install', '--upgrade', pkg])

甚至:

import pipcommands = ['install', '--upgrade']pkgs = commands.extend([p.key for p in pip.get_installed_distributions()])pip.main(commands)

它工作得很快,因为它不会不断地发射炮弹。

import osimport pipfrom subprocess import call, check_call
pip_check_list = ['pip', 'pip3']pip_list = []FNULL = open(os.devnull, 'w')

for s_pip in pip_check_list:try:check_call([s_pip, '-h'], stdout=FNULL)pip_list.append(s_pip)except FileNotFoundError:pass

for dist in pip.get_installed_distributions():for pip in pip_list:call("{0} install --upgrade ".format(pip) + dist.project_name, shell=True)

我拿了Ramana的回答,并使它成为PIP3友好。

我最近一直在使用pur。它简单明了。它更新您的requirements.txt文件以反映升级,然后您可以像往常一样使用requirements.txt文件升级。

$ pip install pur...Successfully installed pur-4.0.1
$ purUpdated boto3: 1.4.2 -> 1.4.4Updated Django: 1.10.4 -> 1.10.5Updated django-bootstrap3: 7.1.0 -> 8.1.0All requirements up-to-date.
$ pip install --upgrade -r requirements.txtSuccessfully installed Django-1.10.5 ...

更强大的解决方案

对于pip3,使用这个:

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

对于pip,只需删除3即可:

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

OS X Oddity

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

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

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

  • 由于更改pip命令行功能而导致的可移植性问题
  • 由于常见的pip或pip3子进程故障而导致xargs崩溃
  • 来自原始xargs输出的拥挤日志记录
  • 依赖于Python-to-OS桥,同时可能升级它3

上述命令使用最简单、最可移植的pip语法与edsh相结合来完全克服这些问题。可以使用注释版本2仔细检查ed操作的详细信息。


详情

[1]在Linux4.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 signsed="s/^([^=# \t\\][^ \t=]*)=.*"
# Separate the output of package upgrades with a blank linesed="$sed/echo"
# Indicate what package is being processedsed="$sed; echo Processing \1 ..."
# Perform the upgrade using just the valid package namesed="$sed; pip3 install -U \1"
# Output the commandssed="$sed/p"
# Stream edit the list as above# and pass the commands to a shellpip3 freeze --local | sed -rn "$sed" | sh

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

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

因为没有简单的方法可以逐个升级包,并更新requirements.txt文件,所以我为所选择的包(或所有包)编写了这个平地机还会更新#0文件中的版本

安装

pip install pip-upgrader

用法

激活你的虚拟环境(很重要,因为它还会在当前的虚拟环境中安装升级包的新版本)。

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

pip-upgrade

高级用法

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

pip-upgrade path/to/requirements.txt

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

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

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

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

这是Python 3的PowerShell解决方案:

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

对于Python 2:

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

这将一个接一个地升级包。所以

pip3 checkpip2 check

之后应该确保没有依赖关系被破坏。

如果你在macOS上,

  1. 确保您已安装自制
  2. 安装jq以读取即将生成的JSON
brew install jq
  1. 更新pip3 list --outdated生成的过时包列表中的每个项目
pip3 install --upgrade  `pip3 list --outdated --format json | jq '.[] | .name' | awk -F'"' '{print $2}'`
python -c 'import pip; [pip.main(["install", "--upgrade", d.project_name]) for d in pip.get_installed_distributions()]'

一个班轮!

我在pip问题讨论中找到的最简单和最快的解决方案是:

pip install pipdatepipdate

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

用途:

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

我能找到的最短和最简单的:

pip install -U $(pip freeze | cut -d"=" -f1)

$(cmd)键允许您包装任何shell命令行(它返回其输出)。

正如另一个回答所说:

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

是一个可能的解决方案:这里的一些评论,包括我自己,在使用此命令时遇到了权限问题。对以下内容的一点更改为我解决了这些问题。

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

注意添加的sudo -H允许命令以root权限运行。

使用AWK更新包:

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

windowsPowerShell更新

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

cmd中的一行:

for /F "delims= " %i in ('pip list --outdated --format=legacy') do pip install -U %i

所以一个

pip check

之后应该确保没有依赖关系被破坏。

如果你想升级仅由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

#0(基于这个旧脚本)完成了这项工作。根据留档

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

在Windows上最短和最简单。

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

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}

如果列表中没有破损的包装或特殊的轮子,它可以顺利工作…

查看所有过期的包裹

 pip list --outdated --format=columns

安装

 sudo pip install pipdate

然后键入

 sudo -H pipdate

如果您安装了pip<22.3,则使用纯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)dopip install -U ${p%%=*}done

在此之后,您将拥有pip>=22.3,其中-o--format freeze是互斥的,并且您不能再使用此单行代码。

使用pip升级!…最后版本2019

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

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

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

在此处输入图片描述

注:我是该工具的作者。

JSON+jq答案:

pip list -o --format json | jq '.[] | .name' | xargs pip install -U

下面的Windowscmd代码段执行以下操作:

  • 升级pip到最新版本。
  • 升级所有过时的软件包。
  • 对于每个正在升级的包,检查requirements.txt是否有任何版本说明符。
@echo offSetlocal EnableDelayedExpansionrem https://stackoverflow.com/questions/2720014/
echo Upgrading pip...python -m pip install --upgrade pipecho.
echo Upgrading packages...set upgrade_count=0pip list --outdated > pip-upgrade-outdated.txtfor /F "skip=2 tokens=1,3 delims= " %%i in (pip-upgrade-outdated.txt) do (echo ^>%%iset package=%%iset latest=%%jset requirements=!package!
rem for each outdated package check for any version requirements:set dotest=1for /F %%r in (.\python\requirements.txt) do (if !dotest!==1 (call :substr "%%r" !package! _substrrem check if a given line refers to a package we are about to upgrade:if "%%r" NEQ !_substr! (rem check if the line contains more than just a package name:if "%%r" NEQ "!package!" (rem set requirements to the contents of the line:echo requirements: %%r, latest: !latest!set requirements=%%r)rem stop testing after the first instance found,rem prevents from mistakenly matching "py" with "pylint", "numpy" etc.rem requirements.txt must be structured with shorter names going firstset dotest=0)))rem pip install !requirements!pip install --upgrade !requirements!set /a "upgrade_count+=1"echo.)
if !upgrade_count!==0 (echo All packages are up to date.) else (type pip-upgrade-outdated.txt)
if "%1" neq "-silent" (echo.set /p temp="> Press Enter to exit...")exit /b

:substrrem string substition done in a separate subroutine -rem allows expand both variables in the substring syntax.rem replaces str_search with an empty string.rem returns the result in the 3rd parameter, passed by reference from the caller.set str_source=%1set str_search=%2set str_result=!str_source:%str_search%=!set "%~3=!str_result!"rem echo !str_source!, !str_search!, !str_result!exit /b

以下是通过pip更新所有Python 3包(在激活的virtualenv中)的代码:

import pkg_resourcesfrom subprocess import call
for dist in pkg_resources.working_set:call("python3 -m pip install --upgrade " + dist.project_name, shell=True)

在蝙蝠脚本中

call pip freeze > requirements.txtcall powershell "(Get-Content requirements.txt) | ForEach-Object { $_ -replace '==', '>=' } | Set-Content requirements.txt"call pip install -r requirements.txt --upgrade

要在默认python版本中升级所有pip默认包,只需在终端或命令提示符中运行底部python代码:

import subprocessimport re

pkg_list = subprocess.getoutput('pip freeze')
pkg_list = pkg_list.split('\n')

new_pkg = []for i in pkg_list:re.findall(r"^(.*)==.*", str(i))new = re.findall(r"^(.*)==.*", str(i))[0]new_pkg.append(new)
for i in new_pkg:print(subprocess.getoutput('pip install '+str(i)+' --upgrade'))

在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 list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

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

Linux壳上更新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替换为pip3pip2作为您的python版本。
  • pip list --outdated检查过时的pip包。
  • 我的pip版本22.0.3上的--format只有3种类型:列(默认)、冻结或jsonfreeze在命令管道中是更好的选择。
  • 保持命令简单和可用尽可能多的系统。
  1. 通过使用pip升级
  • 使用这个库,您可以轻松升级所有依赖包这些是你遵循的设置。

安装pip升级程序

PIP升级路径/of/requirements_txt_file

一个交互式pip需求升级程序。因为逐个包升级需求是一件麻烦事。它还会更新requirements.txt文件中的版本。

改用pipx:

pipx upgrade-all