在学习Python的时候,最经常遇到的问题就是包版本的问题,比如说这个应用需要libtool包的1.1.1版本,而之前开发的应用则只能运行在1.0.1版本上。那么怎么让两个应用都能够正常运行起来呢?聪明的开发者们提出了虚拟环境的概念,就像电脑的虚拟机一样,创建一个虚拟环境就像创建了虚拟机。你在虚拟环境里做任何操作都不会影响到其他的虚拟环境,也不会影响到系统环境。同时你也可以在你的虚拟环境里安装任何版本的包来进行测试。
在昨天的文章里介绍了Python使用的比较多的一个虚拟环境管理包virtualenv,这个包用在windows系统上比较多。而在Linux/Unix系统上用的比较多的是另外一个虚拟环境管理工具pyenv。
什么是pyenv
pyenv是一个虚拟环境管理工具,可以同时管理多个Python版本,并能以这些Python版本为模板来创建不同的虚拟环境,而且可以灵活的在这些虚拟环境之间进行切换。它具有以下优点:
- 可以直接修改全局Python版本(慎重操作,危险)
- 每个项目一个Python版本
- 从多个Python版本中同时搜索命令,方便测试跨版本软件。
安装
目前这个软件还不支持在windows系统上使用,暂时只支持在Linux和Unix上安装。对于macOS,可以使用Homebrew来安装,官方文档上对应的链接是:https://github.com/pyenv/pyenv#homebrew-on-macos
对于Linux/Unix用户来说,有两种安装方式,第一种是根据官方文档来一步步安装,步骤如下:
- 克隆安装软件。命令是
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
- 定义环境变量
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
对于使用zsh的用户,需要把~/.bash_profile
改成~/.zshrc
。
对于使用Ubuntu的用户,需要把~/.bash_profile
改成~/.bashrc
- 将pyenv init命令添加到shell里已启用shims和自动补全,shims是用于多版本Python选择的工具,添加命令如下:
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\neval "$(pyenv init -)"\nfi' >> ~/.bash_profile
对于使用zsh的用户,需要把~/.bash_profile
改成~/.zshrc
。
对于使用Ubuntu的用户,需要把~/.bash_profile
改成~/.bashrc
- 重启shell让配置的命令生效,可以退出shell重新登录,也可以执行命令:
$ exec "$SHELL"
$ curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
注意:需要提前安装好git,因为它也是先通过git克隆到本地。
脚本执行过程如下:
% Total% Received % XferdAverage SpeedTimeTimeTimeCurrent
DloadUploadTotalSpentLeftSpeed
100148100148002000:00:070:00:07 --:--:--39
10024541002454009400:00:260:00:26 --:--:--668
Cloning into '/root/.pyenv'...
remote: Enumerating objects: 670, done.
remote: Counting objects: 100% (670/670), done.
remote: Compressing objects: 100% (503/503), done.
remote: Total 670 (delta 335), reused 255 (delta 76), pack-reused 0
Receiving objects: 100% (670/670), 380.59 KiB | 30.00 KiB/s, done.
Resolving deltas: 100% (335/335), done.
....
Cloning into '/root/.pyenv/plugins/pyenv-which-ext'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 10 (delta 1), reused 6 (delta 0), pack-reused 0
Unpacking objects: 100% (10/10), done.
这中间会克隆多个包,输出信息比较长,内容类似,所以这里省略了一部分。脚本执行完毕以后,会提示你,没有把pyenv添加到PATH路径,然后你根据它的提示添加一下。提示内容如下所示:
WARNING: seems you still have not added 'pyenv' to the load path.# Load pyenv automatically by adding
# the following to ~/.bashrc:export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
我们需要执行的操作是,打开
~/.bashrc
文件,把最下面三行添加进去,添加好的~/.bashrc
文件如下所示:# .bashrc# User specific aliases and functionsalias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'# Source global definitions
if [ -f /etc/bashrc ];
then
. /etc/bashrc
fi
export PATH="/root/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
保存退出,然后执行一下命令:
source ~/.bashrc
让配置生效。
使用
到这里,pyenv就已经安装好了。然后我们执行命令
pyenv versions
:[root@adminnode ~]# pyenv versions
* system (set by /root/.pyenv/version)
这个命令不是查看pyenv的版本的,而是查看当前系统上安装了哪几个版本的Python,正常情况下刚安装好只有一个system,对应的是系统的python版本。例如CentOS7默认是python2.7,而CentOS 8现在默认是python3.6。
因此如果我们想使用其他版本的python作为虚拟环境的模板时,就需要自己来安装对应的版本,比如现在Python的最新版本已经到了3.8.2版本,我希望以这个版本来作为模板。那么我就需要安装3.8.2。
安装编译python需要的依赖包
yum install -y gcc make patch gdbm-devel openssl-devel sqlite-devel \
readline-devel zlib-devel bzip2-devellibffi-devel
下载python源码包 这一步如果是在国内的服务器或虚拟机上建议操作,因为我们自己不下载的话,pyenv它默认会到python.org的官网上去下载源码包,因为不同地区的网络环境不一样,可能会导致这一步特别慢,甚至会直接失败。因此我们推荐首先自己到python官网下载好源码包。然后上传到你的服务器上,然后拷贝到pyenv的缓存目录中,如下所示:
[root@adminnode ~]# ls
anaconda-ks.cfgPython-3.8.2.tar.xz
[root@adminnode ~]# mkdir ~/.pyenv/cache
[root@adminnode ~]#
[root@adminnode ~]# cp Python-3.8.2.tar.xz ~/.pyenv/cache/
然后再执行安装命令的时候,它就会自动使用缓存里的源码包,这样安装速度就会比较快。
安装
[root@adminnode ~]# pyenv install 3.8.2
Installing Python-3.8.2...
Installed Python-3.8.2 to /root/.pyenv/versions/3.8.2
耐心等待它安装完成,这里安装命令后面直接跟上python对应的版本号即可。安装完成后,所有版本的python都是安装在/root/.pyenv/versions目录下,如下所示:
[root@adminnode ~]# ls /root/.pyenv/versions/
3.8.2
然后我们再查看已经安装的版本信息,就能够看到新安装的3.8.2,如下所示:
[root@adminnode ~]# pyenv versions
* system (set by /root/.pyenv/version)
3.8.2
使用 既然模板搭建好了,那么我们现在就可以使用这个模板来创建我们需要的虚拟环境。在创建之前我们需要说几个注意的点:
- 当前模板中安装了某个包,那么以这个模板创建的虚拟环境中就会有这个包。
- 虚拟环境创建以后,模板中新安装的包不会出现在虚拟环境中。也就是说虚拟环境一旦创建,虚拟环境和模板就是两个完全隔离的环境了。
pyenv virtualenvtemplate_versionvirtualenv_name
template_version指的是模板的版本号,virutalenv_name指的是虚拟环境名词,一般是你的项目的名称。假设我们要开发一个cmdb项目,那么我们就来创建一个cmdb的虚拟环境,如下所示:
[root@adminnode ~]# pyenv virtualenv 3.8.2 cmdb
Looking in links: /tmp/tmp_42mjdiv
Requirement already satisfied: setuptools in /root/.pyenv/versions/3.8.2/envs/cmdb/lib/python3.8/site-packages (41.2.0)
Requirement already satisfied: pip in /root/.pyenv/versions/3.8.2/envs/cmdb/lib/python3.8/site-packages (19.2.3)
[root@adminnode ~]# pyenv versions
* system (set by /root/.pyenv/version)
3.8.2
3.8.2/envs/cmdb
cmdb
这个时候就能看到创建好的虚拟环境名称,但是也可以看到当前目录下的python版本还是system,那么怎么切换到cmdb版本呢?
pyenv是以目录为单位来进行版本控制的,比如说你单独一个项目有一个项目目录,我在项目目录下设置好这个项目的python版本,那么项目的子目录全部会自动继承这个配置。设置目录的python版本命令是:
pyenv local virtualenv_name
示例如下:
[root@adminnode ~]# mkdir cmdb
[root@adminnode ~]# ls
anaconda-ks.cfgcmdbdockerPython-3.8.2.tar.xz
[root@adminnode ~]# cd cmdb
[root@adminnode cmdb]# pyenv local cmdb
(cmdb) [root@adminnode cmdb]#
在上面的代码中我们可以看到,切换到项目cmdb目录下以后,设置该目录的虚拟环境为cmdb,然后我们从shell的提示符中可以看到,前面多了一个(cmdb)的提示,表示我们进入到虚拟环境了,也就是说这个时候就是一个独立的python开发环境。我们看一下这个目录的内容,如下所示:
(cmdb) [root@adminnode cmdb]# ls -al
total 8
drwxr-xr-x. 2 root root29 Mar3 11:29 .
dr-xr-x---. 9 root root 4096 Mar3 11:24 ..
-rw-r--r--. 1 root root5 Mar3 11:29 .python-version
(cmdb) [root@adminnode cmdb]# cat .python-version
cmdb
可以看到多了一个隐藏文件.python-version,文件内容是cmdb,也就是说pyenv是通过这个文件来控制当前目录下的虚拟环境。
- 虚拟环境的删除
pyenv virtualenv-delete virtualenv_name
但是删除之前,建议你通过虚拟环境的pip命令导出虚拟环境下的包列表,命令是:
pip freeze --all> requirements.txt
将已安装的包导出到requirements.txt文件中,然后再删除这个虚拟环境:
(cmdb) [root@adminnode cmdb]# pyenv virtualenv-delete cmdb
pyenv-virtualenv: remove /root/.pyenv/versions/3.8.2/envs/cmdb? y
[root@adminnode cmdb]# ls -al
total 12
drwxr-xr-x. 2 root root53 Mar3 11:41 .
dr-xr-x---. 9 root root 4096 Mar3 11:24 ..
-rw-r--r--. 1 root root5 Mar3 11:29 .python-version
-rw-r--r--. 1 root root31 Mar3 11:41 requirements.txt
[root@adminnode cmdb]# cat .python-version
cmdb
删除完成后,当前目录下的.python-version文件还存在,但是因为找不到对应的虚拟环境信息,此时就无法生效。
【python|Linux系统Python虚拟环境管理软件pyenv】以上就是pyenv的配置和使用基本信息,如果对内容比较感兴趣可以留言大家一起讨论。
推荐阅读
- Whoosh(Python 的轻量级搜索工具)
- 程序员合集|Pygame实战(升级后的2048小游戏—解锁新花样,根本停不下来【附源码】)
- Python|【Pygame小游戏】炸裂全场、超级炸弹人“爆炸”登场,这是你的童年嘛()
- Python 列表解析式竟然支持异步()
- 编程语言|程序员最讨厌的11句话 | 每日趣闻
- python|Python-OpenCV-图像通过透视变换矫正
- docker|Docker项目部署docker+flask+gunicorn
- Docker系列|【Docker系列】Python Flask + Redis 练习程序
- Python每日一练|Python每日一练(牛客新题库)——第11天(循环语句)