• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

Python环境及版本管理工具:virtualenv、virtualenvwrapper及pyenv

Python闲聊 彭东稳 8年前 (2017-04-18) 34093次浏览 已收录 0个评论

一、virtualenv

Python 的背后有着庞大的开源社区支持,但是有一个缺点就是每个包的质量都参差不齐,如果我们在工作服务器上去测试安装每个包,就会造成整个的服务器形成庞大复杂的第三方包依赖。virtualenv 是一个 Python 环境配置和切换的工具,可以用它配置多个 Python 运行环境,和系统中的 Python 环境隔离,即所谓的沙盒。使用沙盒的好处,包括:

  • 解决库之间的版本依赖,比如同一系统上不同应用依赖同一个库的不同版本。
  • 解决权限限制,比如你没有 root 权限。
  • 尝试新的工具,而不用担心污染系统环境。

首先,我们用pip安装 virtualenv:

然后,假定我们要开发一个新的项目,需要一套独立的 Python 运行环境,可以这么做,先创建项目目录:

创建一个独立的 Python 运行环境为 myproject 项目,命名为 test:

命令virtualenv就可以创建一个独立的 Python 运行环境,我们还加上了参数--no-site-packages,这样,已经安装到系统 Python 环境中的所有第三方包都不会复制过来,这样,我们就得到了一个不带任何第三方包的“干净”的 Python 运行环境。

新建的 Python 环境被放到当前目录下的 test 目录。有了 test 这个 Python 环境,可以用source进入该环境:

注意到命令提示符变了,有个(test)前缀,表示当前环境是一个名为 test 的 Python 环境。

下面正常安装各种第三方包:

在 test 环境下,用 pip 安装的包都被安装到 test 这个环境下,系统 Python 环境不受任何影响。也就是说,test 环境是专门针对 myproject 这个应用创建的。

退出当前的 test 环境,使用deactivate命令:

使用 virtualenv 可以创建多个项目,然后在每个项目运行不同的应用环境,它们相互之间并无干扰。

virtualenv 是如何创建“独立”的 Python 运行环境的呢?原理很简单,就是把系统 Python 复制一份到 virtualenv 的环境,用命令source test/bin/activate进入一个 virtualenv 环境时,virtualenv 会修改相关环境变量,让命令pythonpip均指向当前的 virtualenv 环境。

二、virtualenvwrapper

“wrapper” 的中文意思是包装,由此看出,virtualenvwrapper 就是对 virtualenv 的一个包装。我们在使用 virtualenv 时可以看出,virtualenv 的一个最大的缺点就是,每次开启虚拟环境之前要去虚拟环境所在目录下的 bin 目录下 source 一下 activate,这就需要我们记住每个虚拟环境所在的目录。它没有帮我们整合从而快速切入,一种可行的解决方案是,将所有的虚拟环境目录全都集中起来,比如放到 ~/virtualenvs/,并对不同的虚拟环境使用不同的目录来管理。这就是 virtualenvwrapper 诞生的原因。并且,它还省去了每次开启虚拟环境时候的 source 操作,使得虚拟环境更加好用。

在 Python3 下安装 virtualenvwrapper 也很简单,直接使用 pip 即可。

安装成功后,首先需要对 virtualenvwrapper 进行配置。它需要指定一个环境变量,叫做 WORKON_HOME,用来设置存放 virtualenv 的统一管理目录。并且需要运行一下它的初始化工具 virtualenvwrapper.sh,这个脚本在对应 Python 版本的 bin 目录下。

由于每次都需要执行这两部操作,我们可以将其写入终端的配置文件中。例如,如果使用 bash,则添加到 ~/.bashrc 中;如果使用 zsh,则添加到 ~/.zshrc 中。这样每次启动终端的时候都会自动运行。

变量 VIRTUALENVWRAPPER_VIRTUALENV_ARGS 用来给定生成独立运行环境时的参数,加上参数--no-site-packages,表示已经安装到系统 Python 环境中的所有第三方包都不会复制过来,这样,我们就得到了一个不带任何第三方包的“干净”的 Python 运行环境。

变量 VIRTUALENVWRAPPER_PYTHON 可以用来指定运行的 Python 版本,可选。

都完成之后,就可以 source .bashrc 一下,然后就可以使用 virtualenvwarpper 了。

首先,可以使用 mkvirtualenv 创建一个虚拟环境,如下。

之后我们就有了一个叫做 flask 的虚拟环境,它被存放在 $WORKON_HOME/flask 目录下。

新建虚拟环境之后会自动激活虚拟环境。如果我们平时想要进入某个虚拟环境,可以用下面的命令。

这也就是为什么环境变量中存放虚拟环境的目录为啥叫做 WORKON_HOME。顺便说一句,workon 后面可是可以支持用 tab 自动补全的哟。

当我们想查看我有多少个虚拟环境时,就可以使用 lsvirtualenv 命令了,它会帮我们列出我们使用 mkvirtualenv 命令创建的所有虚拟环境。

同样,离开虚拟环境,可以使用。

另外,当我们删除一个虚拟环境时,也很简单。

当我们 workon 到某个虚拟环境后,比如你想进入到虚拟环境的 site-packages 目录,可以使用 cdsitepackages 命令。如果只是想浏览 site-packages 目录,可以直接使用 lssitepackages 命令。想回到当前虚拟环境根目录,可以使用 cdvirtualenv 命令。基本常用命令就这么多了。

三、pyenv

pyenv 对比 virtualenv 工具来说,解决的问题不同。virtualenv 是一个沙盒,避免环境污染的,而 pyenv 是一个 Python 版本管理器,用来在同一个系统上切换不同的 Python 解释器的,并且 pyenv 是使用 shell 写的,所以容易阅读。经常遇到这样的情况:

  • 系统自带的 Python 是 2.6,自己需要 Python 2.7 中的某些特性;
  • 系统自带的 Python 是 2.x,自己需要 Python 3.x;

此时需要在系统中安装多个 Python,但又不能影响系统自带的 Python,即需要实现 Python 的多版本共存。pyenv 就是这样一个 Python 版本管理器。

1. 安装Pyenv

在终端执行如下命令以安装pyenv及其插件(安装 pyenv 全家桶):

内容除了包含 pyenv 以外,还包含如下插件(在 $HOME/.pyenv/plugins 目录下存放):

  • pyenv-doctor
  • pyenv-installer
  • pyenv-update
  • pyenv-virtualenv
  • pyenv-which-ext

默认会安装在当前用户家目录下。安装完成后,根据提示将如下语句加入到 ~/.bash_profile 中:

然后重启终端即可。

2. 查看Python可安装版本

查看可安装的版本(pyenv 仅支持此范围内版本安装,如果想扩展可以自行修改 pyenv 代码)

该命令会列出可以用 pyenv 安装的 Python 版本。列表很长,仅列举其中几个:

其中 2.7.14 和 3.6.5 这种只有版本号的是 Python 官方版本,其他的形如 anaconda3-5.1.0 这种既有名称又有版本后的属于 “衍生版” 或发行版。还有如:ironpython、jython、pypy、pyston 等。

3. 安装Python的依赖包

在编译 Python 过程中会依赖一些其他库文件,因而需要首先安装这些库文件,已知的一些需要预先安装的库如下。

在 CentOS/RHEL/Fedora 下:

在 Ubuntu 下:

4. 安装指定版本

用户可以使用pyenv install安装指定版本的 Python。如果是做科学计算的话,推荐你安装 anaconda3 的最新版本,这是一个专门为科学计算准备的发行版。

执行该命令后,会从给定的网址中下载安装文件 Python-3.6.4.tar.xz。但由于文件很大,通常下载需要很久。建议的做法是,先执行以上命令然后马上中断安装,这样就知道pyenv要下载的文件的链接。然后用户自己用其他更快的方式(比如wget、迅雷等等)从该链接中下载安装文件,并将安装文件移动到 ~/.pyenv/cache 目录下(该目录默认不存在,用户要自行新建)。 然后重新执行pyenv install 3.6.4 -v命令。该命令会检查 cache 目录下已有文件的完整性,若确认无误,则会直接使用该安装文件进行安装。

安装过程中,若出现编译错误,通常是由于依赖包未满足,需要在安装依赖包后重新执行该命令。

5. 更新数据库

在安装 Python 或者其他带有可执行文件的模块之后,需要对数据库进行更新:

查看当前已安装的 Python 版本

其中的星号表示当前正在使用的是系统自带的 Python。

6. 设置Python执行环境

pyenv 可以从三个维度来管理 Python 环境,简称为:当前系统、当前目录、当前 shell。这三个维度的优先级从左到右依次升高,即当前系统的优先级最低、当前shell的优先级最高。

如果想修改系统全局的 Python 环境,可以采用 pyenv global PYTHON_VERSION 命令。该命令执行后会在 $(pyenv root) 目录(默认为~/.pyenv)中创建一个名为 version 的文件(如果该文件已存在,则修改该文件的内容),里面记录着系统全局的 Python 版本号。但是最好不要这么使用,可能会影响系统或其他运行环境。

所以,一般都是通过 pyenv local PYTHON_VERSION 命令来修改当前目录的 Python 环境。命令执行后,会在当前目录中生成一个 .python-version 文件(如果该文件已存在,则修改该文件的内容),里面记录着当前目录使用的 Python 版本号。如下:

其中,输出结果前面的 “*” 表示当前正在使用的版本。查看环境变量,会发现当前目录中的 .python-version 配置优先于系统全局的 ~/.pyenv/version 配置。

另外一种情况,通过执行 pyenv shell PYTHON_VERSION 命令,可以修改当前 shell 的 Python 环境。执行该命令后,会在当前 shell session(Terminal窗口)中创建一个名为 PYENV_VERSION 的环境变量,然后在当前 shell 的任意目录中都会采用该环境变量设定的 Python 版本。此时,当前系统和当前目录中设定的 Python 版本均会被忽略。

7. 确认Python版本

由于我们使用的是当前目录运行模式,所以在当前目录及子目录进入 Python 交互模式就可以看到新版本生效了。

如果在父目录运行则会进入系统自带 Python 环境。

8.  使用pyenv-virtualenv进行环境隔离

经过以上操作,我们在本地计算机中就可以安装多个版本的 Python 运行环境,并可以按照实际需求进行灵活地切换。然而,很多时候在同一个 Python 版本下,我们仍然希望能根据项目进行环境分离,就跟之前我们使用 virtualenv 一样。

在 pyenv 中,也包含这么一个插件,pyenv-virtualenv,可以实现同样的功能。使用方式如下:

其中,PYTHON_VERSION 是具体的 Python 版本号,例如,3.6.4,PROJECT_NAME 是我们自定义的项目名称。比较好的实践方式是,在 PROJECT_NAME 也带上 Python 的版本号,以便于识别。

现假设我们有 mysite 这么一个项目,想针对 Python 2.7.13 和 Python 3.6.4 分别创建一个虚拟环境,那就可以依次执行如下命令(前提是相关 Python 版本包在 pyenv 中已经安装完毕)。

创建完成后,通过执行 pyenv virtualenvs 命令,就可以看到本地所有的项目环境。

创建完工作环境以后,可以通过 activate 和 deactivate 子命令进入或退出一个工作环境。进入工作环境以后,左边的提示符会显示你当前所在的工作环境,以免因为环境太多导致误操作。

接下来,就可以在不同的工作环境使用 pip 安装不同的包版本了。

如果想要删除虚拟环境,则使用:

使用 pyenv 和 python-virtualenv 插件,我们就能够自由地在不同的版本之间进行切换,相比管理 Python 版本,不但节省了时间,也避免了工作过程中的相互干扰。以上便是日常开发工作中常用的 pyenv 命令,基本可以满足绝大多数依赖库环境管理方面的需求。

9. 其他常用功能

pyenv commands:查看 pyenv 支持的所有命令。

pyenv uninstall:卸载某个版本或移除某个项目。

pyenv update:更新 pyenv 及其插件。

Tips:

  • 输入python即可使用新版本的 Python;
  • 系统自带的脚本会以/usr/bin/python的方式直接调用老版本的 Python,因而不会对系统脚本产生影响;
  • 使用pip安装第三方模块时会自动按照到当前的 Python 版本下,不会和系统模块发生冲突。
  • 使用pip安装模块后,可能需要执行pyenv rehash更新数据库;

<参考>

https://www.liaoxuefeng.com/wiki/1016959663602400/1019273143120480


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (2)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!