Python关键点笔记之使用 pyenv 管理多个 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 https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
内容除了包含pyenv
以外,还包含如下插件:
pyenv-doctor
pyenv-installer
pyenv-update
pyenv-virtualenv
pyenv-which-ext
安装完成后,pyenv
命令还没有加进系统的环境变量,需要将如下内容加到~/.zshrc
中,然后执行source ~/.zshrc
。
- export PATH=$HOME/.pyenv/bin:$PATH
- eval "$(pyenv init -)"
- eval "$(pyenv virtualenv-init -)"
完成以上操作后,pyenv
就安装完成了。
- $ pyenv -v
- pyenv 1.0.8
如果不确定pyenv
的环境是否安装正常,可以通过pyenv doctor
命令对环境进行检测。
- $ pyenv doctor
- Cloning /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... yes
- checking for strings.h... yes
- checking for inttypes.h... yes
- checking for stdint.h... yes
- checking for unistd.h... yes
- checking openssl/ssl.h usability... no
- checking openssl/ssl.h presence... no
- checking for openssl/ssl.h... no
- configure: 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 update
- Updating /Users/Leo/.pyenv...
- From https://github.com/yyuu/pyenv
- * branch master -> FETCH_HEAD
- Already up-to-date.
- Updating /Users/Leo/.pyenv/plugins/pyenv-doctor...
- From https://github.com/yyuu/pyenv-doctor
- * branch master -> FETCH_HEAD
- Already up-to-date.
- Updating /Users/Leo/.pyenv/plugins/pyenv-installer...
- From https://github.com/yyuu/pyenv-installer
- * branch master -> FETCH_HEAD
- Already up-to-date.
- Updating /Users/Leo/.pyenv/plugins/pyenv-update...
- From https://github.com/yyuu/pyenv-update
- * branch master -> FETCH_HEAD
- Already up-to-date.
- Updating /Users/Leo/.pyenv/plugins/pyenv-virtualenv...
- From https://github.com/yyuu/pyenv-virtualenv
- * branch master -> FETCH_HEAD
- Already up-to-date.
- Updating /Users/Leo/.pyenv/plugins/pyenv-which-ext...
- From https://github.com/yyuu/pyenv-which-ext
- * branch master -> FETCH_HEAD
- Already up-to-date.
0x05 pyenv的核心使用方法
pyenv
的主要功能如下:
- $ pyenv -h
- Usage: pyenv <command> [<args>]
- Some useful pyenv commands are:
- commands List all available pyenv commands
- local Set or show the local application-specific Python version
- global Set or show the global Python version
- shell Set or show the shell-specific Python version
- install Install a Python version using python-build
- uninstall Uninstall a specific Python version
- rehash Rehash pyenv shims (run this after installing executables)
- version Show the current Python version and its origin
- versions List all Python versions available to pyenv
- which Display the full path to an executable
- whence List all Python versions that contain the given executable
- See `pyenv help <command>' for information on a specific command.
- For full documentation, see: https://github.com/yyuu/pyenv#readme
0x06 查看所有可安装的Python
版本
- $ pyenv install --list
- Available versions:
- 2.1.3
- ...
- 2.7.12
- 2.7.13
- ...
- 3.5.3
- 3.6.0
- 3.6-dev
- 3.6.1
- 3.7-dev
需要注意的是,如果是采用brew
命令安装的pyenv
,可能会发现Python
版本库中没有最新的Python
版本。所以建议还是通过GitHub
源码方式安装pyenv
。
0x07 安装指定版本的Python
环境
- $ pyenv install 3.6.0
- Downloading Python-3.6.0.tar.xz...
- -> https://www.python.org/ftp/python/3.6.0/Python-3.6.0.tar.xz
- Installing 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/version
- 2.7.13
- $ pyenv version
- 2.7.13 (set by /Users/Leo/.pyenv/version)
- $ pyenv global 3.6.0
- $ cat ~/.pyenv/version
- 3.6.0
- $ pyenv version
- 3.6.0 (set by /Users/Leo/.pyenv/version)
通常情况下,对于特定的项目,我们可能需要切换不同的Python环境,这个时候就可以通过pyenv local PYTHON_VERSION
命令来修改当前目录
的Python环境。命令执行后,会在当前目录中生成一个.python-version
文件(如果该文件已存在,则修改该文件的内容),里面记录着当前目录使用的Python版本号。
- $ cat ~/.pyenv/version
- 2.7.13
- $ pyenv local 3.6.0
- $ cat .python-version
- 3.6.0
- $ cat ~/.pyenv/version
- 2.7.13
- $ pyenv version
- 3.6.0 (set by /Users/Leo/MyProjects/.python-version)
- $ pip -V
- pip 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_VERSION
- 3.6.0
- $ cat .python-version
- 2.7.13
- $ pyenv version
- 3.6.0 (set by PYENV_VERSION environment variable)
顾名思义,当前shell
的Python环境仅在当前shell中生效,重新打开一个新的shell后,该环境也就失效了。如果想在当前shell
中取消shell级别的Python环境,采用unset
命令重置PYENV_VERSION
环境变量即可。
- $ cat .python-version
- 2.7.13
- $ pyenv version
- 3.6.0 (set by PYENV_VERSION environment variable)
- $ unset PYENV_VERSION
- $ pyenv version
- 2.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 -V
- pip 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 version
- py27_XDiff (set by /Users/Leo/MyProjects/.python-version)
- (py27_XDiff) ➜ MyProjects python -V
- Python 2.7.13
- (py27_XDiff) ➜ MyProjects pip -V
- pip 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
命令,基本可以满足绝大多数依赖库环境管理方面的需求。
参考
Python关键点笔记之使用 pyenv 管理多个 Python 版本依赖环境的更多相关文章
- python学习笔记--Django入门四 管理站点--二
接上一节 python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...
- 使用 pyenv 管理不同的 Python 版本
1. pyenv 的安装 $ yum install git -y $ yum install gcc make patch gdbm-devel openssl-devel sqlite-devel ...
- Python学习笔记【第一篇】:认识python和基础知识
我的笔记里的python代码运行环境都是在pycharm软件中运行,所以不去记录如何配置环境变量呀什么的. python种类 Cpython: Python的官方版本,使用C语言实现,使用最为广泛,C ...
- python学习笔记--Django入门四 管理站点
上一节 Django入门三 Django 与数据库的交互:数据建模 "管理员界面"是基础功能中的重要部分. django.contrib 包 Django自动管理工具是djang ...
- 使用pyenv管理不同的python版本
1. pvenv的安装 git clone https://github.com/yyuu/pyenv.git ~/.pyenv echo 'export PYENV_ROOT="$HOME ...
- Python学习笔记【第八篇】:Python内置模块
什么时模块 Python中的模块其实就是XXX.py 文件 模块分类 Python内置模块(标准库) 自定义模块 第三方模块 使用方法 import 模块名 form 模块名 import 方法名 说 ...
- #Python学习笔记:1-3章 (基于《python编程,从入门到实践)
第1-3章 这个文档是记录我学习python时一些学习笔记以及一些想法也可以称作复习笔记 第一章:起步这一章主要是从第一个"hello world"程序到python环境的搭建与配 ...
- Python学习笔记4-如何快速的学会一个Python的模块、方法、关键字
想要快速的学会一个Python的模块和方法,两个函数必须要知道,那就是dir()和help() dir():能够快速的以集合的型式列出该模块下的所有内容(类.常量.方法)例: #--encoding: ...
- Python学习笔记【第十三篇】:Python网络编程一Socket基础
什么是⽹络 网络能把双方或多方连在一起的工具,即把数据从一方传递到另一方进行数据传递. 网络编程就是不同电脑上的软件能够进行数据传递.即进程间的通讯. 什么是TCP/IP协议 协议就是大家一起遵守的约 ...
随机推荐
- Inside The C++ Object Model(二)
============================================================================2-0. 关键字explicit被引入C++,提 ...
- 115、如何构建Android MVVM 应用框架(转载)
转载:http://android.jobbole.com/85198/
- 【Python】安装error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools"
pip install Scrapy --> error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft ...
- CF 634A Island Puzzle
A. Island Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- pytest 3.9在python 2.7下的一个bug
最在在使用pytest,用的是pytest 3.9.3,python版本为2.7.10,但一直在使用时发现总提示 File "c:\python27\Lib\json\__init__.py ...
- nvm的安装
安装前可先卸载原来的node, npm, 安装成功后,可用nvm装node 一.用nvm-noinstall.zip安装 1.nvm-windows 下载 https://github.com/cor ...
- Wooden Sticks---(贪心)
Problem Description There is a pile of n wooden sticks. The length and weight of each stick are know ...
- HttpRequest获得服务端和客户端的详细信息
参考文档:http://blog.csdn.net/u012104100/article/details/43051301 http://blog.csdn.net/u011162260/articl ...
- swust oj 1015
堆排序算法 1000(ms) 10000(kb) 2631 / 5595 编写程序堆排序算法.按照从小到大的顺序进行排序,测试数据为整数. 输入 第一行是待排序数据元素的个数: 第二行是待排序的数据元 ...
- C#遍历枚举(Enum)值
foreach (object o in Enum.GetValues(typeof(EmpType))) { Console.WriteLine("{0}:{1}", o, En ...