java中的接口是类吗
198
2022-09-02
Python关键点笔记之使用 pyenv 管理多个 Python 版本依赖环境(python要点和重难点解析)
0x00 背景
从接触Python以来,一直都是采用virtualenv和virtualenvwrapper来管理不同项目的依赖环境,通过workon、mkvirtualenv等命令进行虚拟环境切换,很是愉快。
然而,最近想让项目能兼容更多的Python版本,例如至少同时兼容Python2.7和Python3.3+,就发现采用之前的方式行不通了。
最大的问题在于,在本地计算机同时安装Python2.7和Python3后,即使分别针对两个Python版本安装了virtualenv和virtualenvwrapper,也无法让两个Python版本的workon、mkvirtualenv命令同时生效。另外一方面,要想在本地计算机安装多个Python版本,会发现安装的成本都比较高,实现方式也不够优雅。
幸运地是,针对该痛点,已经存在一个比较成熟的方案,那就是pyenv。
如下是官方的介绍。
# pyenv lets you easily switch between multiple versions of Python. It’s simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.# This project was forked from rbenv and ruby-build, and modified for Python.
本文就针对pyenv最核心的功能进行介绍。
0x01 基本原理
如果要讲解pyenv的工作原理,基本上采用一句话就可以概括,那就是:修改系统环境变量PATH。
对于系统环境变量PATH,相信大家都不陌生,里面包含了一串由冒号分隔的路径,例如/usr/local/bin:/usr/bin:/bin。每当在系统中执行一个命令时,例如python或pip,操作系统就会在PATH的所有路径中从左至右依次寻找对应的命令。因为是依次寻找,因此排在左边的路径具有更高的优先级。
而pyenv做的,就是在PATH最前面插入一个$(pyenv root)/shims目录。这样,pyenv就可以通过控制shims目录中的Python版本号,来灵活地切换至我们所需的Python版本。
如果还想了解更多细节,可以查看pyenv的文档介绍及其源码实现。
0x02 环境初始化
pyenv的安装方式包括多种,重点推荐采用pyenv-installer的方式,原因主要有两点:
通过pyenv-installer可一键安装pyenv全家桶,后续也可以很方便地实现一键升级;pyenv-installer的安装方式基于GitHub,可保证总是使用到最新版本的pyenv,并且Python版本库也是最新最全的。
0x03 install && config
通过如下命令安装pyenv全家桶。
$ curl -L | bash
内容除了包含pyenv以外,还包含如下插件:
pyenv-doctorpyenv-installerpyenv-updatepyenv-virtualenvpyenv-which-ext
安装完成后,pyenv命令还没有加进系统的环境变量,需要将如下内容加到~/.zshrc中,然后执行source ~/.zshrc。
export PATH=$HOME/.pyenv/bin:$PATHeval "$(pyenv init -)"eval "$(pyenv virtualenv-init -)"
完成以上操作后,pyenv就安装完成了。
$ pyenv -vpyenv 1.0.8
如果不确定pyenv的环境是否安装正常,可以通过pyenv doctor命令对环境进行检测。
$ pyenv doctorCloning /Users/Leo/.pyenv/plugins/pyenv-doctor/bin/.....Installing python-pyenv-doctor...BUILD FAILED (OS X 10.12.3 using python-build 20160602)Last 10 log lines:checking for memory.h... yeschecking for strings.h... yeschecking for inttypes.h... yeschecking for stdint.h... yeschecking for unistd.h... yeschecking openssl/ssl.h usability... nochecking openssl/ssl.h presence... nochecking for openssl/ssl.h... noconfigure: error: OpenSSL development header is not installed.make: *** No targets specified and no makefile found. Stop.Problem(s) detected while checking system.
通过检测,可以发现本地环境可能存在的问题,例如,从以上输出可以看出,本地的OpenSSL development header还没有安装。根据提示的问题,逐一进行修复,直到检测不再出现问题为止。
0x04 update
通过pyenv update命令,可以更新pyenv全家桶的所有内容。
$ pyenv updateUpdating /Users/Leo/.pyenv...From * branch master -> FETCH_HEADAlready up-to-date.Updating /Users/Leo/.pyenv/plugins/pyenv-doctor...From * branch master -> FETCH_HEADAlready up-to-date.Updating /Users/Leo/.pyenv/plugins/pyenv-installer...From * branch master -> FETCH_HEADAlready up-to-date.Updating /Users/Leo/.pyenv/plugins/pyenv-update...From * branch master -> FETCH_HEADAlready up-to-date.Updating /Users/Leo/.pyenv/plugins/pyenv-virtualenv...From * branch master -> FETCH_HEADAlready up-to-date.Updating /Users/Leo/.pyenv/plugins/pyenv-which-ext...From * branch master -> FETCH_HEADAlready up-to-date.
0x05 pyenv的核心使用方法
pyenv的主要功能如下:
$ pyenv -hUsage: pyenv
需要注意的是,如果是采用brew命令安装的pyenv,可能会发现Python版本库中没有最新的Python版本。所以建议还是通过GitHub源码方式安装pyenv。
0x07 安装指定版本的Python环境
$ pyenv install 3.6.0Downloading Python-3.6.0.tar.xz...-> Python-3.6.0...Installed Python-3.6.0 to /Users/Leo/.pyenv/versions/3.6.0
0x08 查看当前系统中所有可用的Python版本
$ pyenv versions* system (set by /Users/Leo/.pyenv/version) 2.7.13 3.6.0
0x09 切换Python版本
pyenv可以从三个维度来管理Python环境,简称为:当前系统、当前目录、当前shell。这三个维度的优先级从左到右依次升高,即当前系统的优先级最低、当前shell的优先级最高。
如果想修改系统全局的Python环境,可以采用pyenv global PYTHON_VERSION命令。该命令执行后会在$(pyenv root)目录(默认为~/.pyenv)中创建一个名为version的文件(如果该文件已存在,则修改该文件的内容),里面记录着系统全局的Python版本号。
$ pyenv global 2.7.13$ cat ~/.pyenv/version2.7.13$ pyenv version2.7.13 (set by /Users/Leo/.pyenv/version)$ pyenv global 3.6.0$ cat ~/.pyenv/version3.6.0$ pyenv version3.6.0 (set by /Users/Leo/.pyenv/version)
通常情况下,对于特定的项目,我们可能需要切换不同的Python环境,这个时候就可以通过pyenv local PYTHON_VERSION命令来修改当前目录的Python环境。命令执行后,会在当前目录中生成一个.python-version文件(如果该文件已存在,则修改该文件的内容),里面记录着当前目录使用的Python版本号。
$ cat ~/.pyenv/version2.7.13$ pyenv local 3.6.0$ cat .python-version3.6.0$ cat ~/.pyenv/version2.7.13$ pyenv version3.6.0 (set by /Users/Leo/MyProjects/.python-version)$ pip -Vpip 9.0.1 from /Users/Leo/.pyenv/versions/3.6.0/lib/python3.6/site-packages (python 3.6)
可以看出,当前目录中的.python-version配置优先于系统全局的~/.pyenv/version配置。
另外一种情况,通过执行pyenv shell PYTHON_VERSION命令,可以修改当前shell的Python环境。执行该命令后,会在当前shell session(Terminal窗口)中创建一个名为PYENV_VERSION的环境变量,然后在当前shell的任意目录中都会采用该环境变量设定的Python版本。此时,当前系统和当前目录中设定的Python版本均会被忽略。
$ echo $PYENV_VERSION$ pyenv shell 3.6.0$ echo $PYENV_VERSION3.6.0$ cat .python-version2.7.13$ pyenv version3.6.0 (set by PYENV_VERSION environment variable)
顾名思义,当前shell的Python环境仅在当前shell中生效,重新打开一个新的shell后,该环境也就失效了。如果想在当前shell中取消shell级别的Python环境,采用unset命令重置PYENV_VERSION环境变量即可。
$ cat .python-version2.7.13$ pyenv version3.6.0 (set by PYENV_VERSION environment variable)$ unset PYENV_VERSION$ pyenv version2.7.13 (set by /Users/Leo/MyProjects/.python-version)
0x0A 管理多个依赖库环境
经过以上操作,我们在本地计算机中就可以安装多个版本的Python运行环境,并可以按照实际需求进行灵活地切换。然而,很多时候在同一个Python版本下,我们仍然希望能根据项目进行环境分离,就跟之前我们使用virtualenv一样。
在pyenv中,也包含这么一个插件,pyenv-virtualenv,可以实现同样的功能。
使用方式如下:
$ pyenv virtualenv PYTHON_VERSION PROJECT_NAME
其中,PYTHON_VERSION是具体的Python版本号,例如,3.6.0,PROJECT_NAME是我们自定义的项目名称。比较好的实践方式是,在PROJECT_NAME也带上Python的版本号,以便于识别。
现假设我们有XDiff这么一个项目,想针对Python 2.7.13和Python 3.6.0分别创建一个虚拟环境,那就可以依次执行如下命令。
$ pyenv virtualenv 3.6.0 py36_XDiff$ pyenv virtualenv 2.7.13 py27_XDiff
创建完成后,通过执行pyenv virtualenvs命令,就可以看到本地所有的项目环境。
$ pyenv virtualenvs 2.7.13/envs/py27_XDiff (created from /Users/Leo/.pyenv/versions/2.7.13)* 3.6.0/envs/py36_XDiff (created from /Users/Leo/.pyenv/versions/3.6.0) py27_XDiff (created from /Users/Leo/.pyenv/versions/2.7.13) py36_XDiff (created from /Users/Leo/.pyenv/versions/3.6.0)
通过这种方式,在同一个Python版本下我们也可以创建多个虚拟环境,然后在各个虚拟环境中分别维护依赖库环境。
例如,py36_XDiff虚拟环境位于/Users/Leo/.pyenv/versions/3.6.0/envs目录下,而其依赖库位于/Users/Leo/.pyenv/versions/3.6.0/lib/python3.6/site-packages中。
$ pip -Vpip 9.0.1 from /Users/Leo/.pyenv/versions/3.6.0/lib/python3.6/site-packages (python 3.6)
后续在项目开发过程中,我们就可以通过pyenv local XXX或pyenv activate PROJECT_NAME命令来切换项目的Python环境。
➜ MyProjects pyenv local py27_XDiff(py27_XDiff) ➜ MyProjects pyenv versionpy27_XDiff (set by /Users/Leo/MyProjects/.python-version)(py27_XDiff) ➜ MyProjects python -VPython 2.7.13(py27_XDiff) ➜ MyProjects pip -Vpip 9.0.1 from /Users/Leo/.pyenv/versions/2.7.13/envs/py27_XDiff/lib/python2.7/site-packages (python 2.7)
可以看出,切换环境后,pip命令对应的目录也随之改变,即始终对应着当前的Python虚拟环境。
对应的,采用pyenv deactivate命令退出当前项目的Python虚拟环境。
如果想移除某个项目环境,可以通过如下命令实现。
$ pyenv uninstall PROJECT_NAME
以上便是日常开发工作中常用的pyenv命令,基本可以满足绝大多数依赖库环境管理方面的需求。
参考
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~