Ubuntu使用pyenv管理多版本python
使用pyenv
的初衷是为了解决系统内多个python版本管理混乱的问题。实际开发中,切换版本时由于系统内装了多个python版本,不记得每个版本的别名,甚至不记得都有哪些版本,而pyenv
正好帮我解决了这个痛点。
pyenv
是什么?
pyenv
是一个forked自ruby社区的简单、低调、遵循UNIX哲学的Python环境管理工具, 它可以轻松切换全局解释器版本, 同时结合vitualenv
插件(virtualenvwrapper
自然也可以)可以方便的管理对应的包源。
从官方给出的介绍来看没感觉出来其相对于其他版本管理的工具有什么优势,下面就实际走一遍流程,感受下pyenv
的便捷之处。
安装pyenv
下载pyenv
我这里直接以家目录为例了,很多软件的配置文件等都是以隐藏文件的形式放在家目录下或者根目录下,我们的安装路径设置为~/.pyenv
1 | git clone https://github.com/pyenv/pyenv.git ~/.pyenv |
以上操作会将pyenv
安装到当前用户的~/.pyenv
下
定义环境变量
将以下内容放到~/.bashrc
文件最后
1 | export PATH=~/.pyenv/bin:$PATH |
然后激活pyenv
1 | source ~/.bashrc |
或者直接终端使用echo命令
1 | echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc |
注意:此时需要重启终端,才能使路径更改生效
pyenv
使用
查看可安装的python版本
1 | root@UYYNOT:~# pyenv install --list |
查看已安装的python版本
1 | root@UYYNOT:~# pyenv versions |
此处的system是系统自带的Python版本,Ubuntu
中系统自带2.7和3.5,*代表当前正在使用的python版本
查看当前使用的python版本
1 | root@UYYNOT:~# pyenv version |
安装python版本
安装python依赖包
在安装python之前,要先安装python的一些依赖包,否则会安装失败
1 | sudo apt-get install libc6-dev gcc |
安装python指定版本
1 | root@UYYNOT:~# pyenv install 3.6.15 |
默认从官方下载会比较慢,你可以考虑更换其他源进行下载,但是如果追求最新版本可能国内源就不在你考虑范围了(淘宝源python最新版本为3.9)。
自行下载安装python版本包
1 | cd ~/.pyenv |
此处不确定该淘宝源可用,请自行验证。
更新数据库
1 | root@UYYNOT:~# pyenv rehash |
切换python版本
xxx表示要切换的版本
有三种切换方式 global
local
shell
- **
global
**: 全局环境。在未再次使用global
切换环境之前,一直使用此环境。 - **
local
**: 本次登录环境。重启后,则环境失效,并返回当前global
的环境。 - **
shell
**: 局部(临时)环境。关闭命令行窗口,则环境失效,并返回当前global
的环境。
1 | root@UYYNOT:~# pyenv global 3.10.5 |
验证是否切换成功,经验证已经成功切换至3.10.5
1 | root@UYYNOT:~# pyenv version |
卸载指定python版本
1 | root@UYYNOT:~# pyenv uninstall 3.6.5 |
注意事项:
- 系统自带的脚本会以
/usr/bin/python
的方式直接调用老版本的python,因而不会对系统脚本产生影响。 - 使用pip安装第三方模块时会安装到
~/.pyenv/versions/3.6.5
下,不会和系统模块发生冲突。 - 使用pip安装模块后,可能需要执行
pyenv rehash
更新数据库。
pyenv-virtualenv
使用
virtualenv
python虚拟环境。将一个目录建立为一个虚拟的python环境, 这样的话, 用户可以建立多个虚拟环境, 每个环境里面的python版本可以是不同的, 也可以是相同的, 而且环境之间相互独立。
首先我们可以用pyenv
安装多个python 版本, 比如安装了2.5, 2.6, 3.3 三个版本。 用户可以随意切换当前默认的python版本。 但这时候, 每个版本的环境仍是唯一的, 如果我们想在环境中安装一些库的话, 还是会导致这个版本的环境被修改。 这个时候, 如果我们用virtualenv
去建立虚拟环境, 就可以完全保证系统路径的干净。无论你在虚拟环境中安装了什么程序, 都不会影响已安装版本的系统环境
安装pyenv-virtualenv
pyenv
已经帮我们以plugin
的形式安装好了。如果未安装,则需要我们手动安装一下。我们的pyenv
的安装目录是~/.pyenv
,所以我们需要把pyenv-virtualenv
克隆到~/.pyenv/plugins
下,执行下面的命令
1 | git clone https://github.com/pyenv/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv |
配置环境变量
1 | echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc |
创建虚拟环境
1 | root@UYYNOT:~# pyenv virtualenv 3.8.5 py_test_3_8_5 |
验证是否创建环境成功
1 | root@UYYNOT:~# ls .pyenv/versions |
使用虚拟环境
1 | root@UYYNOT:~# pyenv activate py_test_3_8_5 |
退出虚拟环境
1 | (py_test_3_8_5) root@UYYNOT:~# pyenv deactivate |
删除虚拟环境
1 | root@UYYNOT:~# rm -rf ~/.pyenv/versions/py_test_3_8_5 |
注意事项
当我们使用pyenv virtualenv
创建虚拟环境的时候,验证环境是否创建成功的时候,不知道大家有没有注意到最后一行。
1 | root@UYYNOT:~# ll .pyenv/versions |
可以看见虚拟环境并不是直接创建在了~/.pyenv/versions/
,而只是创建了一个软连接,实际指向的位置在要创建的python版本下的envs
文件夹内,所以当你使用rm -rf ~/.pyenv/versions/py_test_3_8_5
去删除虚拟环境时,其实删除的只是一个软连接。
1 | 查看当前已安装的python版本 |
通过以上操作可以看出,虚拟环境并没有被我们删除,我们还需要去python版本对应的envs
下删除实际创建的虚拟环境
1 | root@UYYNOT:~# rm -rf .pyenv/versions/3.8.5/envs/py_test_3_8_5/ |
pyenv-virtualenvwrapper
没有使用pyenv的时候,对于virtualenv环境的混乱,我们通常会使用virtualenvwrapper来管理,主要是每次开启虚拟环境之前要去虚拟环境所在目录下的 bin
目录下 source
一下 activate
,这就需要我们记住每个虚拟环境所在的目录。
并且还有可能你忘记了虚拟环境放在哪。。。
- 一种可行的解决方案是,将所有的虚拟环境目录全都集中起来,例如
/opt/all_venv/
,并且针对不同的目录做不同的事。 - 使用
virtualenvwrapper
管理你的虚拟环境(virtualenv
),其实他就是统一管理虚拟环境的目录,并且省去了source
的步骤。
但是我们现在使用了pyenv
,将virtualenv
作为其一个插件来使用,我们可以使用pyenv activate
tab自动回填方式确定已有环境,而且各个环境包也都统一管理在一个目录里,但是,这并不意味着我们使用pyenv-virtualenv
没有缺点
删除虚拟环境麻烦,需要手动删除软连接和虚拟环境实际目录(上面已经提到过)
使用
pyenv-virtualenv
创建虚拟环境对于pyenv来说相当于创建了一个python版本,会与pyenv安装的python版本混在一起,并且会重复显示创建的虚拟环境和软连接,如下:1
2
3
4
5
6
7
8
9
10
11
12
13root@UYYNOT:~/.pyenv/versions/3.8.5/envs# pyenv virtualenv 3.10.5 pyenv_31005
created virtual environment CPython3.10.5.final.0-64 in 351ms
creator CPython3Posix(dest=/root/.pyenv/versions/3.10.5/envs/pyenv_31005, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/root/.local/share/virtualenv)
added seed packages: pip==23.0, setuptools==67.1.0, wheel==0.38.4
activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
root@UYYNOT:~/.pyenv/versions/3.8.5/envs# pyenv versions
system
3.8.5
3.10.5
3.10.5/envs/pyenv_31005
* 3.11.1 (set by PYENV_VERSION environment variable)
pyenv_31005可以看到
pyenv_31005
和3.10.5/envs/pyenv_31005
本来是一个,重复跟pyenv
安装的python版本混在一起,后续进行python版本切换的时候也会让你一脸懵。我们使用
pyenv
切换版本至虚拟环境时退不出来,只能通过切换到其他版本才能退出来(也就是你只能在pyenv activate
时才能用pyenv deactivate
退出)1
2
3
4
5
6root@UYYNOT:~# pyenv shell pyenv_31005
(pyenv_31005) root@UYYNOT:~# pyenv deactivate
(pyenv_31005) root@UYYNOT:~# python -V
Python 3.10.5
(pyenv_31005) root@UYYNOT:~# pyenv shell 3.11.1
root@UYYNOT:~#
以上就是我用pyenv-virtualenv
的感受,虽然缺点说了这么多,但也有一个很显眼的优点就是创建虚拟环境时可以指定python版本,而pyenv-virtualenvwrapper
只能切换到指定python版本创建对应的虚拟环境。
安装 pyenv-virtualenvwrapper
作为 pyenv
插件
将 pyenv-virtualenvwrapper
安装为 pyenv
插件将使您能够访问 pyenv virtualenvwrapper
andpyenv virtualenvwrapper_lazy
命令。
1 | git clone https://github.com/pyenv/pyenv-virtualenvwrapper.git ~/.pyenv/plugins/pyenv-virtualenvwrapper |
这会将最新开发版本的 pyenv-virtualenvwrapper
安装到$(您的pyenv目录)/plugins/pyenv-virtualenvwrapper
目录中。从该目录中,您可以签出特定的发布标签。要更新 pyenv-virtualenvwrapper
,请运行git pull
以下载最新的更改。
激活
安装完成后使用下列命令激活pyenv-virtualenvwrapper
:
1 | pyenv virtualenvwrapper |
或者,如果你喜欢virtualenvwrapper_lazy.sh
,
1 | pyenv virtualenvwrapper_lazy |
配置文件
要让 virtualenvwrapper
使用pyvenv
而不是创建虚拟环境virtualenv
,请设置 PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV
环境变量和环境存放目录。例如,在您的.bashrc
配置中设置以下内容:
1 | export PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV="true" |
最后一行pyenv virtualenvwrapper_lazy
是为了让你每次打开shell,自动激活pyenv-virtualenvwrapper
,可以直接使用virtualenvwrapper
命令。
使配置生效
1 | source .bashrc |
pip安装virtualenvwrapper
第一次使用新的 Python 环境需要安装此包,否则创建的虚拟环境 Python 版本仍为系统默认,要在pyenv
里安装的每个python版本中安装virtualenvwrapper
包才可使用
其实使用一下命令即可为当前python版本安装virtualenvwrapper
,并且如果第一个版本装过后,切换版本的话会利用缓存进行安装,速度上快很多。
我们已经将该条语句写入了.bashrc
文件中,当你source .bashrc
时,会自动为你安装
1 | pyenv virtualenvwrapper_lazy |
或者使用以下命令,相对较慢
1 | pip install virtualenvwrapper |
查看是否安装
1 | root@UYYNOT:~# pyenv version |
以上可以看出我们每个python版本都安装好了virtualenvwrapper
。
使用virtualenvwrapper
创建虚拟环境
依次切换我们的python版本,创建测试虚拟环境
1 | root@UYYNOT:~# python -V |
查看已创建的虚拟环境
使用workon
直接回车
1 | root@UYYNOT:~# workon |
或者lsvirtualenv
1 | root@UYYNOT:~# lsvirtualenv |
使用指定虚拟环境
1 | root@UYYNOT:~# workon 3085_bbb |
进入当前使用的虚拟环境目录
1 | (3105_aaa) root@UYYNOT:~# cdvirtualenv |
进入当前使用的虚拟环境site-packages目录
1 | (3105_aaa) root@UYYNOT:~# cdsitepackages |
显示 当前虚拟环境site-packages 目录中的内容。
1 | (3105_aaa) root@UYYNOT:~# lssitepackages |
退出虚拟环境
1 | (3085_bbb) root@UYYNOT:~# deactivate |
删除指定虚拟环境
1 | root@UYYNOT:~# rmvirtualenv 3085_bbb |
查看虚拟环境目录
1 | root@UYYNOT:~/.virtualenvs# ll |
刚才删除3085_bbb虚拟环境这里也同步删除了