Python多环境管理神器(pyenv)
前面我们已经介绍了,python中两种最基础的虚拟环境管理工具,venv和virtualenv,其中virtualenv可以和virtualenvwrapper配合使用。详情请参考:https://www.cnblogs.com/doublexi/p/15783355.html
下面我们来介绍另一个python多环境管理神器pyenv
pyenv
pyenv 主要用来对 Python 解释器进行管理,可以管理系统上的多个版本的 Python 解释器。它的主要原理就是将新的解释器路径放在 PATH 环境变量的前面,这样新的 python 程序就“覆盖”了老的 python 程序,达到了切换解释器的目的。
pyenv-virtualenv虚拟环境管理也是一样,shims管理各个虚拟环境命令的路径,然后再将shims路径插入到系统环境变量最前面,达到切换虚拟环境的目的。
1、安装pyenv:
pyenv不是自带的,需要额外安装。
方式一:
使用git来安装:
01 | git clone https: //github .com /pyenv/pyenv .git ~/.pyenv |
配置环境变量:
01 02 03 04 05 06 07 08 09 10 11 12 13 | sed -Ei -e '/^([^ #]|$)/ {a \ export PYENV_ROOT= "$HOME/.pyenv" a \ export PATH= "$PYENV_ROOT/bin:$PATH" a \ ' -e ' :a ' -e ' $!{n;ba};}' ~/.bash_profile echo 'eval "$(pyenv init --path)"' >> ~/.bash_profile echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile echo 'eval "$(pyenv init --path)"' >> ~/.profile echo 'eval "$(pyenv init -)"' >> ~/.bashrc |
请注意,以上的三条 echo 命令的最后一条长长的命令,请你保证它引号中的内容处于 ~/.bashrc 或者 ~/.zshrc 的最底部。
因为在 pyenv 初始化期间会操作 path 环境变量,导致不可预测的行为。
重启当前shell,加载新的环境变量
01 | exec $SHELL -l |
测试是否安装成功:
01 02 | [root@ops-130 ~] # pyenv versions * system ( set by /root/ .pyenv /version ) |
安装过程如下:
此时,表示pyenv安装成功。
安装方式二:
直接使用别人写好的脚本一键安装:
01 | curl -L https: //github .com /pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash |
安装脚本有可能会提示你手动把几行命令添加到shell的配置文件中。
将来要进行更新的话:
01 | pyenv update |
要卸载pyenv的话更加简单,直接删除目录即可:
01 | rm -fr ~/.pyenv |
别忘了把.bashrc中的这几行也一并删掉:
01 02 03 | export PATH= "~/.pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" |
2、python环境管理
2.1、解释器版本安装与切换
使用pyenv安装指定python版本
01 | pyenv install 2.7.8 |
安装过程中,可能会显示缺少一些包,补上就好了。
先安装依赖包:
01 02 | yum install patch -y pyenv install 2.7.8 |
安装成功如下:
安装新版本后,需要rehash一下
01 | pyenv rehash |
查看当前版本:
01 02 03 04 05 | # 查看当前版本 pyenv version # 查看 pyenv 已经托管了哪些 python 版本 pyenv versions |
当前版本为系统使用版本:
切换当前目录的python版本为2.7.8
01 | pyenv local 2.7.8 |
再次查看当前python版本,发现已经切换了。
查看所有可安装的软件版本
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | [root@ops-130 ~] # pyenv install -l Available versions: 2.1.3 ... 2.7.15 ... 3.6.6 3.7.0 3.7-dev 3.8-dev activepython-2.7.14 activepython-3.5.4 activepython-3.6.0 anaconda-1.4.0 ... anaconda3-5.2.0 ironpython-dev ironpython-2.7.4 ironpython-2.7.5 ironpython-2.7.6.3 ironpython-2.7.7 jython-dev jython-2.5.0 jython-2.5-dev jython-2.5.1 jython-2.5.2 jython-2.5.3 jython-2.5.4-rc1 jython-2.7.0 jython-2.7.1 micropython-dev micropython-1.9.3 micropython-1.9.4 miniconda-latest miniconda-2.2.2 ... miniconda3-4.3.30 pypy-c-jit-latest pypy-c-nojit-latest pypy-dev pypy-stm-2.3 pypy-stm-2.5.1 pypy-1.5-src pypy-1.5 ... pypy3.5-6.0.0 pyston-0.5.1 pyston-0.6.0 pyston-0.6.1 stackless-dev stackless-2.7-dev stackless-2.7.2 ... stackless-3.5.4 |
2.2、virutalenv 使用 pyenv 安装的 python 版本
01 02 | // 通过 -p 参数指定 pyenv 安装的 python 3.3.3 的 bin 目录 # virtualenv -p /root/.pyenv/versions/3.3.3/bin/python3.3 py3.3 |
2.3、三种解释器版本控制方法比较(global、shell、local)
pyenv控制版本的方式有三种,分别是:global、shell、local,下面分别来看看这三种方式:
首先是pyenv shell会话设置:(只影响当前会话)
会话一:
01 02 03 04 05 06 07 08 09 10 11 12 13 | [root@ops-130 ~] # pyenv versions * system ( set by /root/ .pyenv /version ) 2.7.8 3.3.3 # pyenv修改python版本 [root@ops-130 ~] # pyenv shell 3.3.3 [root@ops-130 ~] # pyenv versions system 2.7.8 * 3.3.3 ( set by PYENV_VERSION environment variable) [root@ops-130 ~] # python -V Python 3.3.3 [root@ops-130 ~] # |
可以看到,使用pyenv shell切换会话里的python版本后,
会话1的pyenv和python显示版本均为3.3.3
会话二:
重新打开一个会话窗口,查看python版本
01 02 03 04 05 06 07 08 09 10 | WARNING! The remote SSH server rejected X11 forwarding request. Last login: Tue Jan 4 09:28:51 2022 from 192.168.90.197 [root@ops-130 ~] # cd /data/ [root@ops-130 data] # pyenv versions * system ( set by /root/ .pyenv /version ) 2.7.8 3.3.3 [root@ops-130 data] # python -V Python 2.7.5 [root@ops-130 data] # |
可以看到新打开的会话是Python 2.7.5,并没有受到影响,所以shell只会影响到当前的会话,一旦这个会话结束,则一切失效
pyenv local本地设置(只影响当前目录)
它会在当前目录创建一个.python-version文件,里面记录着版本内容
新建目录/data/test
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | [root@ops-130 test ] # pyenv versions * system ( set by /root/ .pyenv /version ) 2.7.8 3.3.3 # pyenv local修改python版本 [root@ops-130 test ] # pyenv local 3.3.3 [root@ops-130 test ] # pyenv versions system 2.7.8 * 3.3.3 ( set by /data/test/ .python-version) [root@ops-130 test ] # python -V Python 3.3.3 # 在当前目录生成.python-version版本文件 [root@ops-130 test ] # ls -a . .. .python-version test2 [root@ops-130 test ] # cat .python-version 3.3.3 |
创建一个子目录test2
01 02 03 04 05 06 07 08 | [root@ops-130 test ] # mkdir test2 [root@ops-130 test ] # cd test2 [root@ops-130 test2] # pyenv versions system 2.7.8 * 3.3.3 ( set by /data/test/ .python-version) [root@ops-130 test2] # python -V Python 3.3.3 |
发现子目录也随之一起改变了
再回到父目录查看:
父目录不变。
所以pyenv local命令只会对当前的文件夹和其子目录中的版本起作用 ,其他的目录不起作用
01 02 03 04 05 06 07 | [root@ops-130 test ] # cd .. [root@ops-130 data] # pyenv versions * system ( set by /root/ .pyenv /version ) 2.7.8 3.3.3 [root@ops-130 data] # python -V Python 2.7.5 |
pyenv global 全局设置
如果使用此命令,可以看到所有受到pyenv控制的窗口都受到了影响, 所以尽可能不要用root用户来安装pyenv,否则会影响到之前的系统
原理是:
该命令执行后会在 $(pyenv root) 目录(默认为 ~/.pyenv )中创建一个名为 version 的文件(如果该文件已存在,则修改该文件的内容),里面记录着系统全局的Python版本号。
01 02 03 04 05 06 07 08 09 10 11 12 | # 全局设置,会覆盖所有的目录和窗口 [root@ops-130 ~] # pyenv global 2.7.8 [root@ops-130 ~] # pyenv versions system * 2.7.8 ( set by /root/ .pyenv /version ) 3.3.3 # 会在~/.pyenv中创建version文件 [root@ops-130 ~] # ls /root/.pyenv/ bin CHANGELOG.md completions Dockerfile LICENSE man pyenv.d shims terminal_output.png version cache COMMANDS.md CONDUCT.md libexec Makefile plugins README.md src test versions [root@ops-130 ~] # cat /root/.pyenv/version 2.7.8 |
切换到其他目录查看:
01 02 03 04 05 06 | # opt也被改成了2.7.8 [root@ops-130 test ] # cd /opt/ [root@ops-130 opt] # pyenv versions system * 2.7.8 ( set by /root/ .pyenv /version ) 3.3.3 |
切换到之前local设置的目录:local并没有被global覆盖
01 02 03 04 05 | [root@ops-130 ~] # cd /data/test/ [root@ops-130 test ] # pyenv versions system 2.7.8 * 3.3.3 ( set by /data/test/ .python-version) |
如果要取消pyenv的版本设置:
01 02 03 04 05 06 | # 取消当前shell窗口的 pyenv shell -- unset # 取消当前目录的 pyenv local -- unset # 取消全局设置 pyenv global system |
优先级比较: shell > local > global
更多命令使用,参考官网:https://github.com/pyenv/pyenv/blob/master/COMMANDS.md#pyenv-local
3、虚拟环境管理 (pyenv-virtualenv)
3.1、安装pyenv-virtualenv
pyenv要使用虚拟环境管理,必须安装一个插件pyenv-virtualenv
01 02 03 | git clone https: //github .com /pyenv/pyenv-virtualenv .git ~/.pyenv /plugins/pyenv-virtualenv echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bash_profile source ~/.bash_profile |
查看是否安装成功:
01 | pyenv help virtualenv |
如下图:
3.2、虚拟环境创建与切换
使用pyenv创建虚拟环境(不需要指定目录)
01 02 | # 直接创建虚拟环境myproj3,它不需要指定目录,不会在当前目录生成myproj3目录文件 pyenv virtualenv 3.3.3 myproj3 |
如下图:会发现多出了两个python的环境
查看虚拟环境列表:
01 | pyenv virtualenvs |
如下图:
激活虚拟环境:
01 | pyenv activate myproj3 |
如下图,环境已经激活,切换到了myproj3环境中,虚拟环境名已经出现在前缀上。
退出虚拟环境
01 | pyenv deactivate |
如下图:
删除虚拟环境:
01 02 | # 直接卸载该环境 pyenv uninstall myproj3 |
如下图:
3.3、虚拟环境隔离原理:(shims原理)
观察PATH路径,可以发现,pyenv的虚拟环境隔离是通过插入shims路径到PATH头部,实现的。
01 | cat $PATH |
shims路径如下:里面都是一些经常使用的命令引用路径,pip、python等。
当切换虚拟环境时,pyenv就会将对应环境的命令拷贝,覆盖掉shims路径下的命令,并在PATH的头部插入shims路径,来实现python版本的切换。
01 02 03 04 05 06 | (myproj3) [root@ops-130 ~] # ls /root/.pyenv/shims/ 2to3 easy_install idle pip pip3 pydoc3 python2 python2.7- gdb .py python3.3 python3.3m-config pyvenv wheel 2to3-3.3 easy_install-2.7 idle3 pip2 pip3.3 pydoc3.3 python2.7 python2-config python3.3-config python3-config pyvenv-3.3 activate easy_install-3.3 idle3.3 pip2.7 pydoc python python2.7-config python3 python3.3m python-config smtpd.py (myproj3) [root@ops-130 ~] # which pip /root/ .pyenv /shims/pip |
如下图:
3.4、关于虚拟环境pip没有切换的问题
注意:(PS:使用pyenv-virtualenv创建虚拟环境的时候,经常因为下载pip不成功,导致pip包环境没有切换过来。)
如下图:这里下载pip就没有成功。
此时,我们发现虽然成功创建了虚拟环境myproj,但是里面的pip并没有切换,如下:
01 02 03 04 05 06 07 08 09 10 11 12 13 | # 虽然进入了虚拟环境,python环境切换过来了,但是pip环境还是旧的,没有切换过来 (myproj3) [root@ops-130 ~] # pyenv versions system 2.7.8 3.3.3 3.3.3 /envs/myproj3 * myproj3 ( set by PYENV_VERSION environment variable) (myproj3) [root@ops-130 ~] # python -V Python 3.3.3 # pip环境还是旧的 (myproj3) [root@ops-130 ~] # pip -V pip 8.1.2 from /usr/lib/python2 .7 /site-packages (python 2.7) # 此时如果使用pip是无法安装到对应的虚拟环境的 |
进入虚拟环境:我们手动重新安装一下pip
01 | curl https: //bootstrap .pypa.io /pip/3 .3 /get-pip .py | python |
如下图:
再次验证:发现此时pip已经切换过来了,可以使用pip安装软件包了。
01 02 03 04 | (myproj3) [root@ops-130 ~] # which pip /root/ .pyenv /shims/pip (myproj3) [root@ops-130 ~] # pip -V pip 10.0.1 from /root/ .pyenv /versions/myproj3/lib/python3 .3 /site-packages/pip (python 3.3) |
如下图:
4、pyenv+anaconda
pyenv内部集成了anaconda的软件包,可以在pyenv+anaconda环境。
01 02 | # 查看软件库,有很多anaconda的版本,也有miniconda的 pyenv install --list |
安装anaconda3-2.5.0
01 02 03 04 | # anaconda依赖bzip2,先安装这个库 yum install bzip2 -y # pyenv安装anaconda pyenv install anaconda3-2.5.0 |
pyenv使用anaconda环境
# 方法一:直接切换anaconda环境
01 02 03 04 05 06 07 08 09 10 11 12 13 14 | # 方法一:直接切换anaconda [root@ops-130 test ] # pyenv versions system 2.7.8 * 3.3.3 ( set by /data/test/ .python-version) 3.3.3 /envs/myproj3 anaconda3-2.5.0 myproj3 [root@ops-130 test ] # pyenv local anaconda3-2.5.0 # 发现里面python版本也是anaconda自带的版本3.5.1 [root@ops-130 test ] # python -V Python 3.5.1 :: Anaconda 2.5.0 (64-bit) [root@ops-130 test ] # which python /root/ .pyenv /shims/python |
如下图:
方法二:创建使用anaconda的虚拟环境
01 02 03 04 05 06 07 08 09 10 11 12 | # 创建虚拟环境的过程中,它会下载一些包,包括pip之类的。 [root@ops-130 ~] # pyenv virtualenv anaconda3-2.5.0 myproj4 查看当前托管版本: [root@ops-130 ~] # pyenv versions * system ( set by /root/ .pyenv /version ) 2.7.8 3.3.3 3.3.3 /envs/myproj3 anaconda3-2.5.0 anaconda3-2.5.0 /envs/myproj4 myproj3 myproj4 |
激活环境:
01 | [root@ops-130 ~] # pyenv activate myproj4 |
如下图:
接下来,就可以使用conda来安装管理库了,
01 | (myproj4) [root@ops-130 ~] # conda install py4j |
如下图:
退出虚拟环境:
01 | pyenv deactivate |
5、优缺点分析:
1、pyenv极大程度的利用了环境变量工具,通过在环境变量前面插入新路径来实现python解释器版本管理和虚拟环境管理。
2、pyenv相比其他工具,更加侧重在python 解释器版本管理上, 比包管理更大一个层级, 使用pyenv我可以方便的下载指定版本的python解释器, pypy, anaconda等, 可以随时自由的在shell环境中本地、全局切换python解释器
3、开发的时候不需要限定某个版本的虚拟环境, 只需要在部署的时候用pyenv local指定当前项目目录使用某个版本就好了,很方便。
4、pyenv切换解释器版本的时候, pip和ipython以及对应的包环境都是一起切换的。(PS:其他工具也是会一起切换的。)有些场景验证多个版本的代码更方便
(PS:使用pyenv-virtualenv创建虚拟环境的时候,经常因为下载pip不成功,导致pip包环境没有切换过来。不过可以自己进入虚拟环境,再手动安装pip解决这个问题。)
5、pyenv也可以创建好指定的虚拟环境, 但不需要指定具体目录, 自由度更高, 使用也简单
个人常用的做法是为每个项目创建不同的虚拟环境, 当进入该环境的时候就可以随便浪而不用担心影响到其它项目, 搭配Pycharm使用效果更佳.
注意:pyenv 不支持 Windows 系统。Windows 上有一个 pyenv 的替代品,是 pywin 。它用来在多个安装的 Python 版本之间进行切换
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!