阿毛
It's me !
想你所想
python版本管理与虚拟环境

总结下关于pyenv以及virtualenv的理解

一般系统会自带一个python2版本的python,在实际开发中,往往可能使用python3,并且多个项目python版本要求不一样。如果同时开发多个不同版本要求的项目,直接安装多个版本的python是不行的。所以只要解决一个机器上如何并存多个版本的python即可,pyenv孕育而出。

一、pyenv

pyenv是一个管理python版本的工具,可以同时管理多个不同版本的python,并很容易地在多版本之间切换,随时随地使用任意版本的python。

1、安装

如果你是mac系统并安装了homebrew的话,直接brew install pyenv即可。如果是其他的话,可以直接clone仓库安装,当然因为我这里使用的是mac,所以主要阐述mac下操作的情况。

如果安装过程中,遇到与openssl相关的编译报错,则是因为homebrew安装pyenv时会附带安装一个版本的openssl,可以brew uninstall openssl,然后pyenv install v 时会默认下载其所需版本的openssl。

➜  ~ pyenv -v
pyenv 1.2.19

安装完成后,键入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,一直使用的是此虚拟环境。

https://file.blog.humh.cn/2020/11/d2b5ca33bd970f64a6301fa75ae2eb22-11.png

如上图,可以看到,在左边会话中,在test项目下开启虚拟环境,右边会话是不会起作用的。同时,左边会话切出项目目录,虚拟环境仍然生效。可以理解pyenv active原理是改变了当前用户环境变量中的python变量。

在指定项目路径下,pyenv local,该python version仅在当前路径下有效,退出则为系统version,无需在pyenv activate 和deactivate,如下图。

https://file.blog.humh.cn/2020/11/d2b5ca33bd970f64a6301fa75ae2eb22-12.png

pyenv local的原理是在当前项目路径下,生成一个“.python-version”文件,内容就是需生效的python虚拟环境名。当进入项目路径下,如果存在这个文件,则就会改变python环境变量,就像一个局部变量一样,这也就导致pyenv local的虚拟环境只能在某个目录下生效。

发表评论

textsms
account_circle
email

想你所想

python版本管理与虚拟环境
总结下关于pyenv以及virtualenv的理解 一般系统会自带一个python2版本的python,在实际开发中,往往可能使用python3,并且多个项目python版本要求不一样。如果同时开发多个不同版本要…
扫描二维码继续阅读
2020-10-20