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

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


当前回答

查看所有过时的软件包

 pip list --outdated --format=columns

安装

 sudo pip install pipdate

然后键入

 sudo -H pipdate

其他回答

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

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

相关错误报告,从Bitbucket迁移后有点脱节:

https://github.com/pypa/pip/issues/49https://github.com/pypa/pip/issues/59

以下Windows cmd代码段执行以下操作:

将pip升级到最新版本。升级所有过时的软件包。对于正在升级的每个包,检查requirements.txt中的任何版本说明符。

@echo off
Setlocal EnableDelayedExpansion
rem https://stackoverflow.com/questions/2720014/

echo Upgrading pip...
python -m pip install --upgrade pip
echo.

echo Upgrading packages...
set upgrade_count=0
pip list --outdated > pip-upgrade-outdated.txt
for /F "skip=2 tokens=1,3 delims= " %%i in (pip-upgrade-outdated.txt) do (
    echo ^>%%i
    set package=%%i
    set latest=%%j
    set requirements=!package!

    rem for each outdated package check for any version requirements:
    set dotest=1
    for /F %%r in (.\python\requirements.txt) do (
        if !dotest!==1 (
            call :substr "%%r" !package! _substr
            rem 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 first
                set 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


:substr
rem 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=%1
set str_search=%2
set str_result=!str_source:%str_search%=!
set "%~3=!str_result!"
rem echo !str_source!, !str_search!, !str_result!
exit /b

Use:

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

您可以使用以下Python代码。与pip冻结不同,这不会打印警告和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)

对于pip>=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)

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

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)