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

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


当前回答

拉玛纳的回答对我来说是最好的,但我不得不补充几点:

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

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

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

其他回答

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

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)

拉玛纳回答的一个线性版本。

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

这是我对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

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

import pkg_resources
from subprocess import call

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

如果您希望升级仅由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