51

Python 虚拟环境全知道

 6 years ago
source link: https://blog.qikqiak.com/post/python-virtualenv-all-know/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python 虚拟环境全知道

发表于 January 9, 2018

Reach for the End.

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

  • 不同项目间能区分依赖包版本
  • 不同项目间能区分python版本
  • 方便自由切换
  • 解决依赖包问题:virtualenv
  • 解决python版本问题:pyenv
  • 终极(也许吧)解决方案:docker

virtualenv

运行pip install virtualenv即可安装virtualenv,当然了还可以用easy_install安装,即使是没有安装任何Python包管理器(比如pip),也可以直接获取virtualenv.py并运行python virtualenv.py,效果也是一样的,当然我还是强烈推荐你安装包管理工具:pip,他一定能为你带来很多便利的(新版本的virtualenv也包含了pip管理工具)。

$ 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 环境名称):

$ virtualenv env4test

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

$ source env4test/bin/activate
(env4test)$

现在就可以随意的安装你的依赖包了,现在安装的包只会对当前环境env4test有效,比如安装django2.0

(env4test)$ pip install django

要退出当前虚拟环境也是非常简单的,如下:

$ deactivate

现在我们用pip list命令可以发现已经没有django的身影了。

virtualenv还有很多高级的用法,可以前往该文档查看

virtualenvwrapper

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

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

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

$ 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

参考文档:https://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版本: shell $ pyenv install -l
  • 安装与卸载:

    $ pyenv install 2.7.3   # 安装python
    $ pyenv uninstall 2.7.3 # 卸载python
    • 版本切换: shell $ 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版本和依赖包进行环境隔离了,在实际开发过程中比较推荐这种方式。

参考文档:https://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

微信公众号

扫描下面的二维码关注我们的微信公众帐号,在微信公众帐号中回复◉加群◉即可加入到我们的 kubernetes 讨论群里面共同学习。

wechat-account-qrcode

「真诚赞赏,手留余香」


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK