Python 虚拟环境全知道

对于每一个python项目依赖的库版本都有可能不同,若是将依赖包都安装到公共环境的话显然是无法进行区分的,甚至是不一样的项目使用的python版本都不尽相同,有的用python2.7,有的用python3.6,因此对于python项目的环境进行隔离管理就成为一个必然的需求了。python

需求

  • 不一样项目间能区分依赖包版本
  • 不一样项目间能区分python版本
  • 方便自由切换

解决方案

  • 解决依赖包问题:virtualenv
  • 解决python版本问题:pyenv
  • 终极(也许吧)解决方案:docker

virtualenv

运行pip install virtualenv便可安装virtualenv,固然了还能够用easy_install安装,即便是没有安装任何Python包管理器(好比pip),也能够直接获取virtualenv.py并运行python virtualenv.py,效果也是同样的,固然我仍是强烈推荐你安装包管理工具:pip,他必定能为你带来不少便利的(新版本的virtualenv也包含了pip管理工具)。git

$ pip install virtualenv
Collecting virtualenv
  Using cached virtualenv-15.1.0-py2.py3-none-any.whl
Installing collected packages: virtualenv
Successfully installed virtualenv-15.1.0
复制代码

安装完成后,就能够直接建立一个虚拟环境了(virtualenv 环境名称):github

$ virtualenv env4test
复制代码

建立完成后,用下面的命令便可激活当前虚拟环境:docker

$ source env4test/bin/activate
(env4test)$
复制代码

如今就能够随意的安装你的依赖包了,如今安装的包只会对当前环境env4test有效,好比安装django2.0shell

(env4test)$ pip install django
复制代码

要退出当前虚拟环境也是很是简单的,以下:django

$ deactivate
复制代码

如今咱们用pip list命令能够发现已经没有django的身影了。缓存

virtualenv还有不少高级的用法,能够前往该文档查看bash

virtualenvwrapper

virtualenvwrappervirtualenv的一个扩展包,可让你更加方便的使用virtualenv,优势:微信

  • 将全部虚拟环境整合在一个目录下
  • 管理(新增,删除,复制)虚拟环境
  • 方便切换虚拟环境

安装也很方便,用包管理工具便可:app

$ pip install virtualenvwrapper
复制代码

安装完成之后还须要小小的配置一下才可使用,首先咱们找到virtualenvwrapper.sh的文章,一般会是:/usr/local/bin/virtualenvwrapper.sh

$ sudo find / -name virtualenvwrapper.sh
Password:
/usr/local/bin/virtualenvwrapper.sh
复制代码

而后咱们能够在.zshrc(取决于你用的终端,我用的zsh)添加一行命令:

source /usr/local/bin/virtualenvwrapper.sh
复制代码

而后让咱们的配置生效:

$ source ~/.zshrc
复制代码

如今咱们就可使用virtualenvwrapper的基本命令了:

  • 建立基本环境:mkvirtualenv [环境名]
  • 删除环境:rmvirtualenv [环境名]
  • 激活环境:workon [环境名]
  • 退出环境:deactivate
  • 列出全部环境:workon或者lsvirtualenv -b

参考文档:virtualenvwrapper.readthedocs.io/en/latest/

pyenv

pyenvPython版本管理工具,能够改变全局的Python版本,安装多个版本的Pytho,设置目录级别的Python版本,还能建立和管理虚拟环境。全部的设置都是用户级别的操做,不须要sudo命令。 pyenv经过系统修改环境变量来实现Python不一样版本的切换。而virtualenv 经过将Python包安装到一个目录来做为Python 包虚拟环境,经过切换目录来实现不一样包环境间的切换。

若是你使用的MAC系统,推荐使用homebrew来安装:

$ brew update
$ brew install pyenv
复制代码

若是你使用的是其余系统,也不担忧,pyenv官方提供了一键安装的方式:

$ curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
复制代码

安装完成之后,能够添加几条命令到.zshrc(一样的也多是.bashrc,根据本身使用的终端进行配置)中开启自动补全功能:

export PATH=$HOME/.pyenv/bin:$PATH
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
复制代码

而后一样激活上面的配置:

$ source ~/.zshrc
复制代码

如今咱们就可使用pyenv了:

  • 查看本机安装 Python 版本:
$ pyenv versions
* system (set by /Users/ych/.pyenv/version)
  3.6.4
  3.6.4/envs/ops3.6.4
  3.6.4/envs/talk3.6.4
  ops3.6.4
  talk3.6.4
复制代码

星号表示当前正在使用的Python版本。

  • 查看全部可安装的Python版本:
$ pyenv install -l
复制代码
  • 安装与卸载:
$ pyenv install 2.7.3 # 安装python
$ pyenv uninstall 2.7.3 # 卸载python
复制代码
  • 版本切换:
$ pyenv global 2.7.3
$ pyenv local 2.7.3
复制代码

global用于设置全局的Python版本,经过将版本号写入~/.pyenv/version文件的方式。local用于设置本地版本,经过将版本号写入当前目录下的.python-version文件的方式。经过这种方式设置的Python版本优先级比global高。

  • python优先级:shell > local > global pyenv会从当前目录开始向上逐级查找.python-version文件,直到根目录为止。若找不到,就用global版本。
$ pyenv shell 2.7.3 # 设置面向 shell 的 Python 版本,经过设置当前 shell 的 PYENV_VERSION 环境变量的方式。这个版本的优先级比 local 和 global 都要高。
$ pyenv shell --unset # –unset 参数用于取消当前 shell 设定的版本。
复制代码

pyenv-virtualenv

自动安装pyenv后,它会自动安装部分插件,经过pyenv-virtualenv插件能够很好的和virtualenv进行结合:

$ ls -la ~/.pyenv/plugins
total 8
drwxr-xr-x   9 ych  staff  288 12 26 16:27 .
drwxr-xr-x  23 ych  staff  736 12 26 17:44 ..
-rw-r--r--   1 ych  staff   52 12 26 16:26 .gitignore
drwxr-xr-x  11 ych  staff  352 12 26 16:27 pyenv-doctor
drwxr-xr-x  12 ych  staff  384 12 26 16:27 pyenv-installer
drwxr-xr-x   7 ych  staff  224 12 26 16:27 pyenv-update
drwxr-xr-x  13 ych  staff  416 12 26 16:27 pyenv-virtualenv
drwxr-xr-x   8 ych  staff  256 12 26 16:27 pyenv-which-ext
drwxr-xr-x   8 ych  staff  256 12 26 16:26 python-build
复制代码

基本使用命令:

  • 列出当前虚拟环境:pyenv virtualenvs
  • 激活虚拟环境:pyenv activate 环境名称
  • 退出虚拟环境:pyenv deactivate
  • 删除虚拟环境:pyenv uninstall 环境名称或者rm -rf ~/.pyenv/versions/环境名称
  • 建立虚拟环境:pyenv virtualenv 3.6.4 env3.6.4

若不指定python 版本,会默认使用当前环境python 版本。若是指定Python 版本,则必定要是已经安装过的版本,不然会出错。环境的真实目录位于~/.pyenv/versions下。

总结:利用pyenvpyenv-virtualenv插件就可以简单方便的将python版本和依赖包进行环境隔离了,在实际开发过程当中比较推荐这种方式。

参考文档:github.com/pyenv/pyenv

Docker

有没有一种方式可以不按照这些工具来进行环境隔离的呢?固然有,那就是大名鼎鼎的Docker。若是你的服务都是容器化的话,应该对Docker不陌生,将当前项目跑在一个隔离的容器中,对系统中的其余服务或者项目是没有任何影响的,不用担忧会污染环境,惟一不友好的地方是项目中的代码改变后须要从新构建镜像。

好比如今有一个django的项目,项目结构以下:

$ testpyenv tree
.
├── manage.py
└── testpyenv
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py
复制代码

在项目根目录下面新建文件requirements.txt

Django==2.0
复制代码

而后咱们在根目录下面建立一个Dockerfile文件:

FROM python:3.6.4

# 设置工做目录
RUN mkdir -p /usr/src/app WORKDIR /usr/src/app 
# 添加依赖(利用Docker 的缓存)
ADD ./requirements.txt /usr/src/app/requirements.txt 
# 安装依赖
RUN pip install -r requirements.txt 
# 添加应用
ADD . /usr/src/app 
# 运行服务
CMD python manage.py runserver 0.0.0.0:8000 复制代码

由于django2.0只支持python3以上了,因此咱们这里基础镜像使用python:3.6.4,而后是添加应用代码,安装依赖,运行服务等。而后咱们构建一个镜像:

$ docker build -t cnych/testpyenv:v0.1.1 .
复制代码

构建完成之后,在咱们项目根目录中新建一个start.sh的脚原本启动容器:

docker run -d -p 8000:8000 --name testpyenv cnych/testpyenv:v0.1.1
复制代码

将本地的8000端口和容器的8000进行映射,执行咱们的启动脚本:

$ source start.sh
复制代码

启动完成后,咱们就能够在本地经过http://127.0.0.1:8000进行访问了。

django-index
可是若是只这样配置的话,的确可以解决咱们的环境隔离问题,可是如今有一个最大的一个问题是,每次代码更改事后都须要从新构建镜像才能生效,这对于开发阶段是很是不友好的,有什么解决方案呢?你是否还记得当你更改了代码后 django项目会自动加载的,要是每次更改了项目代码后,容器中的代码也变化的话那岂不是容器中的服务也自动加载了?是否是?

幸亏Docker为咱们提供了volume挂载的概念,咱们只须要将咱们的代码挂载到容器中的工做目录就好了,如今来更改start.sh脚本:

work_path=$(pwd)
docker run -d -p 8000:8000 --name testpyenv -v ${work_path}:/usr/src/app cnych/testpyenv:v0.1.1
复制代码

而后激活启动脚本,随意更改一次代码,看看是否可以及时生效,怎样查看呢?查看日志就好了:

$ docker logs -f testpyenv
复制代码

最后,若是是生产环境记得把代码挂载给去掉,由于线上不须要这样作,只须要构建一次就行。

参考资料:

点击查看原文连接

扫描下面的二维码(或微信搜索iEverything)添加我微信好友(注明python),而后能够加入到咱们的python讨论群里面共同窗习

qrcode
相关文章
相关标签/搜索