总结下关于pyenv以及virtualenv的理解
一般系统会自带一个python2版本的python,在实际开发中,往往可能使用python3,并且多个项目python版本要求不一样。如果同时开发多个不同版本要求的项目,直接安装多个版本的python是不行的。所以只要解决一个机器上如何并存多个版本的python即可,pyenv孕育而出。
一、pyenv
pyenv是一个管理python版本的工具,可以同时管理多个不同版本的python,并很容易地在多版本之间切换,随时随地使用任意版本的python。
1、安装
如果你是mac系统并安装了homebrew的话,直接brew install pyenv
即可。如果是其他的话,可以直接clone仓库安装,当然因为我这里使用的是mac,所以主要阐述mac下操作的情况(补充:Ubuntu的话,运行curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
)。
如果安装过程中,遇到与openssl相关的编译报错,则是因为homebrew安装pyenv时会附带安装一个版本的openssl,可以brew uninstall openssl
,然后pyenv install v
时会默认下载其所需版本的openssl。
➜ ~ pyenv -v pyenv 1.2.19
安装完成后,要想非路径使用,需要配置环境变量(~/.bashrc或~/.zshrc等),
export PATH="/home/humh/.pyenv/bin:$PATH" eval "$(pyenv init -)"
这里我mac安装pyenv后命令集默认位于 /usr/local/bin , 所以直接 export PATH="/usr/local/bin:$PATH"
。
配置完成后,source一下。键入pyenv -v
,如果出现pyenv版本号,即安装成功。
2、使用
2.1、pyenv install
➜ ~ pyenv install --list Available versions: 2.1.3 2.2.3 2.3.7 2.4.0 2.4.1 2.4.2 ..... ➜ ~ pyenv install 2.1.3
pyenv install --list
可以查看到支持安装的所有python版本,然后pyenv install 2.1.3
即可安装2.1.3的版本,当然你可以将2.1.3换成其他版本号。
2.2、pyenv versions
➜ ~ pyenv versions system * 2.7.12 (set by /Users/humh/.pyenv/version) 3.7.0
pyenv versions
可以查看通过pyenv 安装的所有版本python(包含系统自带)。当前生效的python版本前会显示“*”,用于标记。
2.3、pyenv version
➜ ~ pyenv version 2.7.12 (set by /Users/humh/.pyenv/version)
pyenv version
仅输出当前生效的python版本。
2.4、pyenv global
➜ ~ pyenv version 2.7.12 (set by /Users/humh/.pyenv/version) ➜ ~ pyenv versions system * 2.7.12 (set by /Users/humh/.pyenv/version) 3.7.0 ➜ ~ python -V Python 2.7.12 ➜ ~ pyenv global 3.7.0 ➜ ~ pyenv versions system 2.7.12 * 3.7.0 (set by /Users/humh/.pyenv/version) ➜ ~ python -V Python 3.7.0
pyenv global
可以设置全局python,即指定某一版本在全局生效。如上操作,可进行验证。
如果pyenv global $v 后,pyenv versions 查看生效了,但python,未生效,需要配置环境变量,配置 $HOME/.pyenv/bin,最终输入python,会通过垫片机制,会先找到pyenv中配置的python version,使用对应版本python。
关于pyenv local
的使用,见下文阐述。
二、pyenv virtualenv
往往在开发中,你可能遇到这样一种情况,多个项目共用的是同一个版本的python,如果不同项目中都使用了某个pip依赖,但版本却不同,这是就无法解决了,就算没有版本冲突,多个项目的依赖包也会打入同一site-package路径下,这样会很臃肿。
为了解决这个问题,出现了virtualenv工具,它在同一python版本的基础上,很好隔离项目环境。会在项目路径下,生成venv目录。原理就是,它相当于为每一个项目,拷贝了一份python至项目下,所以看似是使用的同一个python,实则是使用拷贝的python。这样每个项目的依赖包都会存在项目自身的python路径中。
对于pyenv来说,同样存在这样需求,根据类似的原理,出现了pyenv-virtualenv工具。
1、 安装
以mac为例,通过brew install pyenv-virtualenv
即可安装。其他情况,可自行百度,暂未实践。
2、使用
➜ ~ pyenv virtualenv 3.7.0 humh_python Looking in links: /var/folders/.. Requirement already satisfied: setuptools in /Users/humh/.pyenv/versions/3.7.0/envs/humh_python/lib/python3.7/site-packages (39.0.1) Requirement already satisfied: pip in /Users/humh/.pyenv/versions/3.7.0/envs/humh_python/lib/python3.7/site-packages (10.0.1) ➜ ~ pyenv versions system 2.7.12 * 3.7.0 (set by /Users/humh/.pyenv/version) 3.7.0/envs/humh_python humh_python
在通过pyenv已经安装了某个版本的python后,通过pyenv virtualenv 3.7.0 humh_python
即可创建一个使用版本3.7.0的虚拟环境,这里你只需将3.7.0和humh_python 换成你需要的python版本号以及虚拟环境名即可,一般虚拟环境名跟你的项目名关联命名。
pyenv versions
会输出你的虚拟环境“humh_python”,这里你应该注意到了,还额外输出了“3.7.0/envs/humh_python”,你可能会好奇这是什么,我们不妨进入pyenv的目录中看看,进入你当前用户的家目录,pyenv工作目录为“.pyenv” (ls -a ~/
即可看到)
➜ ~ cd .pyenv ➜ .pyenv ls cache shims version versions ➜ .pyenv ls cache Python-2.7.12.tar.xz Python-2.7.12.tar.xz.1 Python-2.7.12.tar.xz.2 Python-2.7.12.tar.xz.3 Python-2.7.12.tar.xz.4 Python-3.7.0.tar.xz openssl-1.0.2k.tar.gz ➜ .pyenv ls shims ...... ➜ .pyenv cat version 3.7.0 ➜ .pyenv pyenv version 3.7.0 (set by /Users/humh/.pyenv/version) ➜ .pyenv ls versions 2.7.12 3.7.0 humh_python ➜ .pyenv ls versions/3.7.0 bin envs include lib share ➜ .pyenv ls versions/3.7.0/envs/ cvdata humh_python test ➜ .pyenv ls versions/3.7.0/envs/humh_python bin include lib pyvenv.cfg ➜ .pyenv ll versions/ total 64 drwxr-xr-x 8 humh staff 272B 7 16 09:16 2.7.12 drwxr-xr-x 7 humh staff 238B 8 30 15:24 3.7.0 lrwxr-xr-x 1 humh staff 50B 10 20 19:58 humh_python -> /Users/humh/.pyenv/versions/3.7.0/envs/humh_python
结合上述shell内容,阐述下pyenv的目录结构。
- cache:该目录下,为通过pyenv安装的所有版本python安装包。
- shims:未知
- version:注意,非目录,而是file,file内容为当前全局python版本号,即对应
pyenv global
- versions:该目录下包含了安装后的不同版本python,并且还有创建的虚拟环境内容。拿3.7.0版本为例,可以看到除了3.7.0python自身的目录(bin/、include/、lib/ 以及 share/),多了一个“envs/”目录,该目录下包含了一个“humh_python”的目录,其目录下的内容又与3.7.0 python自身内容一致。而versions下的“humh_python”又是软链至3.7.0/envs/humh_python的。所以不难理解,pyenv-virtualenv 工具的作用与virtualenv类似,也是将虚拟环境对应python拷贝了一份,虚拟环境操作的是拷贝后的python,已达到python隔离的目的。
那么如何使得虚拟环境生效呢?pyenv virtualenv提供了两种方式(这里均以“humh_python”作为虚拟环境名举例):
pyenv activate ‘虚拟环境名’ && pyenv deactivate ‘虚拟环境名’
如同virtualenv的使用是一样的,当进入项目路径下,pyenv activate humh_python
就可以激活“humh_python”的虚拟环境,pyenv deactivate humh_python
退出“humh_python”的虚拟环境。
pyenv local ‘虚拟环境名’
在项目路径下,键入pyenv local humh_python
即可使当前项目启用humh_python的虚拟环境。
二者的区别!!
注意,上述两种方式,均可以满足你对虚拟环境的需求,不同之处在于,作用域与原理不同。pyenv activate
是在当前会话session全局下启用此虚拟环境,无论你是否在你的项目目录下,只要没有deactivate,一直使用的是此虚拟环境。
如上图,可以看到,在左边会话中,在test项目下开启虚拟环境,右边会话是不会起作用的。同时,左边会话切出项目目录,虚拟环境仍然生效。可以理解pyenv active
原理是改变了当前用户环境变量中的python变量。
在指定项目路径下,pyenv local
,该python version仅在当前路径下有效,退出则为系统version,无需在pyenv activate 和deactivate,如下图。
pyenv local
的原理是在当前项目路径下,生成一个“.python-version”文件,内容就是需生效的python虚拟环境名。当进入项目路径下,如果存在这个文件,则就会改变python环境变量,就像一个局部变量一样,这也就导致pyenv local
的虚拟环境只能在某个目录下生效。
发表评论