在虚拟环境中升级Python。

353

有没有办法升级虚拟环境中使用的Python版本(例如,如果出现了一个错误修复版本)?

我可以使用pip freeze --local > requirements.txt,然后删除目录并pip install -r requirements.txt,但这需要重新安装大型库,例如numpy,而我经常使用它。

我可以看到这在从2.6升级到2.7等情况下是一个优势,但是对于2.7.x -> 2.7.y呢?


2
虽然你可能能够修改一些路径等来使其正常工作,但你最不希望的是与生产环境略有不同。试想一下,如果各个版本编译方式之间仅有一个差异,那么你将浪费大量时间去追踪错误,从而失去所有节省的时间。所以,我建议花点时间创建一个全新的虚拟环境并重新安装所有必需的组件。 - Sam Dolan
@Simon Walker。完全相同的问题。我必须升级Python 3.5.3以修复错误。 - Mohammed Shareef C
13个回答

218

如果您正在使用Python 3.3+附带的venv模块,它支持--upgrade选项。 根据文档

假设Python已被原地升级,则将环境目录升级为使用此版本的Python。

python3 -m venv --upgrade ENV_DIR

14
我在我的系统上将Python从3.5.1升级到了3.6.4。为了升级虚拟环境中的Python,我必须在命令中明确提到python3.6:python3.6 -m venv --upgrade <path_of_existing_env> - Sarfraaz Ahmed
6
在我的情况下,bin/pythonbin/python3仍然链接到旧的python3.4二进制文件,我不得不手动设置这些链接。另外,是否有一种方法可以删除现在已过时的Python版本? - Jens
8
我收到了一个错误信息:Error: Command '['/Users/me/Sites/site/venv3/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1. 这是什么意思?我没有看到任何正在运行的Python进程,无法升级。 - user305883
1
@user305883 在我将系统Python版本从3.5升级到3.6(并删除3.5)后,我遇到了类似的错误。我不得不重新安装3.5并运行python3.6 -m venv --upgrade ENV_DIR才能使其正常工作。我认为我仍然需要更新ENV_DIR/bin中的一些符号链接。因此,诀窍是在旧版本仍安装的情况下使用的Python版本进行更新。 - AstroFloyd
1
对我没有用:V3.6.8 -> V3.8.10。F:\MyCodes\python\dtprjops>python -m venv --upgrade venv 错误:[Errno 13] 权限被拒绝:'F:\MyCodes\python\dtprjops\venv\Scripts\python.exe' - Allis Gao
显示剩余10条评论

97

你看到了这个吗?如果我没有误解那个回答,你可以尝试在旧的虚拟环境上创建一个新的虚拟环境。你只需要知道哪个Python将使用你的虚拟环境(你需要查看你的虚拟环境版本)。

如果你的虚拟环境安装了与旧环境相同的Python版本,并且升级虚拟环境软件包不是一个选项,你可能需要阅读这篇文章以安装带有所需Python版本的虚拟环境。

编辑

我已经测试过这种方法(在旧环境上创建一个新的虚拟环境),并且对我来说效果很好。如果你从Python 2.6更改到2.7或2.7到3.x,你可能会遇到一些问题,但如果你只在同一版本内进行升级(如你所想要的2.7),你不应该有任何问题,因为所有软件包都存储在相同的文件夹中,适用于两个Python版本(2.7.x和2.7.y软件包都在your_env/lib/python2.7/中)。

如果你更改了虚拟环境的Python版本,你需要为该版本重新安装所有软件包(或者只需将你需要的软件包链接到新版本软件包文件夹中,即:your_env/lib/python_newversion/site-packages)。


22
如果可能的话,他特别不想重新安装任何包。如果你不知道为什么这很重要,显然你从未从源代码安装过numpy ;) 提示:这需要很长时间。 - Antti Haapala -- Слава Україні
4
对我来说没用,看起来也不应该有用:https://github.com/pypa/virtualenv/issues/437 - Kentzo
@Kentzo,你能给我们展示一下你遇到的错误吗?它可能不适用于所有情况,但肯定适用于某些情况。也许如果你展示一下你遇到的错误,我们就可以理解并帮助你... - marianobianchi
2
我试图在旧的virtualenv基础上创建一个新的虚拟环境,并且成功了。我确实需要指定-p来指向正确版本的Python。 - Sergey Orshanskiy
无论如何,升级虚拟环境之前不要从系统中删除旧的Python版本,否则您将无法执行安装覆盖本身的技巧。 - dpwr
显示剩余2条评论

34

步骤1: 冻结需求并备份现有环境

pip freeze > requirements.txt
deactivate
mv env env_old

步骤2:安装Python 3.7并激活虚拟环境

sudo apt-get install python3.7-venv
python3.7 -m venv env
source env/bin/activate
python --version

步骤 3: 安装要求

sudo apt-get install python3.7-dev
pip3 install -r requirements.txt

26

再次更新: 以下方法可能在新版本的virtualenv中无法使用。 在尝试修改旧的virtualenv之前,您应该将依赖保存到要求文件(pip freeze > requirements.txt)中,并在其他地方备份。 如果出现任何问题,您仍然可以创建一个新的virtualenv并在其中安装旧的依赖项(pip install -r requirements.txt)。

更新: 我在最初回答问题5个月后更改了答案。以下方法更加方便和稳健。

副作用: 当升级Python到v2.7.8后,在虚拟环境中执行import ssl时,它也会修复Symbol not found: _SSLv2_method异常。

注意: 目前,仅适用于Python 2.7.x


如果您正在使用OS X上的Homebrew Python,请先deactivate所有的虚拟环境,然后升级Python:

brew update && brew upgrade python

运行以下命令(<EXISTING_ENV_PATH> 是您虚拟环境的路径):

cd <EXISTING_ENV_PATH>
rm .Python
rm bin/pip{,2,2.7}
rm bin/python{,2,2.7}
rm -r include/python2.7
rm lib/python2.7/*
rm -r lib/python2.7/distutils
rm lib/python2.7/site-packages/easy_install.*
rm -r lib/python2.7/site-packages/pip
rm -r lib/python2.7/site-packages/pip-*.dist-info
rm -r lib/python2.7/site-packages/setuptools
rm -r lib/python2.7/site-packages/setuptools-*.dist-info

最后,重新创建您的虚拟环境:

virtualenv <EXISTING_ENV_PATH>

通过这样做,可以删除旧的Python核心文件和标准库(以及setuptoolspip),同时保留已安装在site-packages中的自定义库,并且只要它们是纯Python库,就可以正常工作。二进制库可能需要重新安装才能正常运行。

这在我安装了Django的5个虚拟环境中都有效。

顺便说一句,如果之后./manage.py compilemessages无法正常工作,请尝试以下操作:

brew install gettext && brew link gettext --force

我需要删除的唯一文件是 bin/python 文件。 - Koen.
对于一些较旧版本的Python,删除setuptoolspip是必要的。 - Rockallite
1
我还不得不删除 <EXISTING_ENV_PATH>/.Python,因为那会破坏虚拟环境的创建。 - Kiran Jonnalagadda
2
根据此答案,我编写了一个小脚本(并进行了完整归属):https://www.burgundywall.com/post/update-all-python-virtual-environments - Kurt
你可以通过运行 rmvirtualenv <env_name> 来轻松删除虚拟环境,并将其所有相关依赖项一并删除 :) 更多信息请参见:http://virtualenvwrapper.readthedocs.io/en/latest/command_ref.html#rmvirtualenv - Nick Lucas
@Nick Lucas 其实,我想保留所有的依赖项,同时删除核心 Python 文件和标准库 :) - Rockallite

13

如何升级现有的virtualenvwrapper项目的Python版本并保持相同的名称

我为使用Doug Hellmann的杰出的virtualenvwrapper的任何人添加了一个答案,特别是因为现有的答案对我没有帮助。

一些背景:

  • 我在一些使用Python 2和一些使用Python 3的项目上工作;虽然我很想使用python3 -m venv,但它不支持Python 2环境
  • 当我启动一个新项目时,我使用mkproject创建虚拟环境,创建一个空项目目录,并切换到该目录
  • 我想继续使用virtualenvwrapper的workon命令来激活任何项目,无论Python版本如何

说明:

假设您的现有项目名称为foo,当前正在运行Python 2(mkproject -p python2 foo),尽管无论从2.x升级到3.x,还是从3.6.0升级到3.6.1等,命令都是相同的。我也假定您目前处于已激活的虚拟环境中。

1. 停用并删除旧的虚拟环境:

$ deactivate
$ rmvirtualenv foo
请注意,如果您已经向挂钩(例如bin/postactivate)添加了任何自定义命令,则需要在删除环境之前保存这些命令。
将真实项目存储在临时目录中:
$ cd ..
$ mv foo foo-tmp

3. 创建新的虚拟环境(和项目目录)并激活:

$ mkproject -p python3 foo

4. 用真实的项目目录替换空的生成项目目录,切换回项目目录:

$ cd ..
$ mv -f foo-tmp foo
$ cdproject

5. 重新安装依赖项,确认新的Python版本等:

$ pip install -r requirements.txt
$ python --version
如果这是一个常见的用例,我会考虑打开一个PR,添加类似于$ upgradevirtualenv / $ upgradeproject到virtualenvwrapper。

2
是的,请。我进行到一半时遇到了很大的问题...如果第一步被删除(据我目前所知),就不可逆了,检查一下会很好。 - chris Frisina
1
我发现有必要为我的Python版本安装distutils,以确保新的mkvirtualenv命令可以无误地工作:sudo apt-get install python3.10-distutils。 - KenBuckley

11

假设你想更新的环境名为 venv

1. 备份 venv 的依赖项(可选)

首先,备份虚拟环境的依赖项:

pip freeze > requirements.txt
deactivate
#Move the folder to a new one
mv venv venv_old

2. 安装 Python

假设没有 sudo 权限,可以使用 pyenv 方便快捷地安装 Python。操作步骤如下:

curl https://pyenv.run | bash

然后

exec $SHELL

此处建议的,您可以使用pyenv-installer安装Pyenv。

如果在更新pyenv时出现问题,请尝试以下方法:

pyenv update

出现错误

bash: pyenv: command not found

这是因为pyenv路径没有导出到.bashrc中。可以通过执行以下命令来解决:

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrc

然后重新启动Shell。

exec "$SHELL"

现在需要安装你想要的Python版本,比如说3.8.3版本。

pyenv install 3.8.3

通过运行以下命令,可以确认是否正确安装:

pyenv versions

输出应该包括位置和版本号(在本例中为3.8.3)。
3.创建新的虚拟环境
最后,安装新的Python版本后,创建一个新的虚拟环境(我们称之为“venv”)。
python3.8 -m venv venv

激活它

source venv/bin/activate

安装所需的软件包

pip install -r requirements.txt

现在您应该已经成功建立了一个新的环境。


7
我无法在旧的虚拟环境之上创建新的虚拟环境。但是pip中有一些工具可以更快地将要求重新安装到全新的venv中。Pip可以将requirements.txt中的每个项目构建为wheel包,并将其存储在本地缓存中。当您创建一个新的venv并在其中运行pip install时,如果找到预构建的wheel包,pip将自动使用它们。与为每个模块运行setup.py相比,Wheels的安装速度更快。
我的~/.pip/pip.conf如下所示:
[global]
download-cache = /Users/me/.pip/download-cache
find-links =
/Users/me/.pip/wheels/

[wheel]
wheel-dir = /Users/me/.pip/wheels

我安装了wheel (pip install wheel),然后运行pip wheel -r requirements.txt。这将在我的pip.conf中的wheel-dir中存储构建好的wheels。

从那时起,每当我pip install这些要求中的任何一个时,它就会从wheels中安装它们,这非常快速。


2
对于大多数人来说,我认为利用pip机制来完成工作是有意义的,但对于那些已经自定义了他们的virtualenvs postactivate、predeactivate等的人来说,这不是一个理想的选择,因为所有这些都会丢失并需要手动重新添加。 - dpwr

5

我想澄清一下,因为有些答案引用了venv,而其他答案则引用了virtualenv

virtualenv支持使用-p--python标志,但venv不支持。如果您有多个Python版本,并且想要指定用哪个版本创建venv,可以在命令行上执行此操作,例如:

malikarumi@Tetuoan2:~/Projects$ python3.6 -m venv {path to pre-existing dir you want venv in}

正如其他人指出的那样,您当然可以使用venv进行升级,但这假定您已经升级了用于首次创建venv的Python。您不能升级到系统上尚未安装的Python版本,因此请确保首先获取所需版本,然后从中创建所有所需的venv。


3

2

如果你正在使用pipenv,我不确定是否可以直接升级环境,但至少对于小版本升级,它似乎足够聪明,在创建新环境时不需要重新构建软件包。 例如,从3.6.4升级到3.6.5:

$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv…
Creating a v$ pipenv --python 3.6.5 install
Virtualenv already exists!
Removing existing virtualenv…
Creating a virtualenv for this project…
Using /usr/local/bin/python3.6m (3.6.5) to create virtualenv…
⠋Running virtualenv with interpreter /usr/local/bin/python3.6m
Using base prefix '/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6'
New python executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python3.6
Also creating executable in /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/python
Installing setuptools, pip, wheel...done.

Virtualenv location: /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD
Installing dependencies from Pipfile.lock (84dd0e)…
     ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 47/47 — 00:00:24
To activate this project's virtualenv, run the following:
 $ pipenv shell
$ pipenv shell
Spawning environment shell (/bin/bash). Use 'exit' to leave.
. /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
bash-3.2$ . /Users/dmoles/.local/share/virtualenvs/autoscale-aBUhewiD/bin/activate
(autoscale-aBUhewiD) bash-3.2$ python
Python 3.6.5 (default, Mar 30 2018, 06:41:53) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>>

你是指这个pipenv吗? - Jens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接