是否可以使用pip一次性升级所有Python包?
注意:官方问题跟踪器上对此有一个功能请求。
是否可以使用pip一次性升级所有Python包?
注意:官方问题跟踪器上对此有一个功能请求。
当前回答
pip_upgrade_outdated(基于此旧脚本)完成此任务。根据其文件:
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
其他回答
我在升级方面也遇到了同样的问题。问题是,我从不升级所有包。我只升级我需要的,因为项目可能会中断。
因为没有一种简单的方法来逐个包升级和更新requirements.txt文件,所以我编写了这个pip升级程序,它还更新了所选包(或所有包)的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参数。
完全披露:我写了这个包裹。
更稳健的解决方案
对于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组件可能会导致死锁或包数据库损坏。
相当惊人的蛋黄使这很容易。
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
它可以做很多你可能会发现有用的事情。
下面是用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安装,并且避免升级由其他工具(如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