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

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


当前回答

我最近一直在用pur。这很简单,切中要害。它会更新您的requirements.txt文件以反映升级,然后您可以像往常一样使用requirements.txt文件进行升级。

$ pip install pur
...
Successfully installed pur-4.0.1

$ pur
Updated boto3: 1.4.2 -> 1.4.4
Updated Django: 1.10.4 -> 1.10.5
Updated django-bootstrap3: 7.1.0 -> 8.1.0
All requirements up-to-date.

$ pip install --upgrade -r requirements.txt
Successfully installed Django-1.10.5 ...

其他回答

还没有内置标志。从pip版本22.3开始,--过时和--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所建议的那样。(是的,您可以用sed、awk、perl或…替换grep+cut)。xargs的-n1标志防止在更新一个包失败时停止所有操作(谢谢@andss)。


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

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

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

一行!

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

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

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

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

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)。