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
相關文章
相關標籤/搜索