Python虛擬環境指南2019版

這是一篇舊文,編寫於2017年,用於公司內部交流。整理更新後於2019年04月06日重發,內容有效期樂觀估計半年,閱讀請注意保質期。html

爲何用python虛擬環境

python版本差別

python當前主要有2個release版本 Python 2.7.16Python 3.7.3 ,這兩個版本在一些語法上存在較大差別。python

若是你從網上下載了一段python代碼,卻運行不起來,首先要排除的是python版本問題。好比下面這個 hello_python.py ,代碼很是簡單,就一句打印 hello,world 到屏幕上。react

print "hello,world"
複製代碼

若是你使用python2.7,恭喜你能夠很好的跑起來,以下:git

(python27) ➜  python hello_python.py
hello,world
複製代碼

若是你使用的是python3,可能就實現從入門到放棄:(docker

(python37) ➜  python hello_python.py
  File "hello_python.py", line 3
    print "hello,world"
                      ^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("hello,world")?
複製代碼

python3 中讓代碼正常運行的辦法和提示同樣,修改語句爲 print("hello,world")npm

python2.7已經 「過期」,pip運行是會提示:django

DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. 複製代碼

現實情況倒是一些庫的版本問題或者歷史遺留問題,可能須要在python2和python3之間切換。flask

python使用場景差別

python語言應用很是普遍,涉及服務器腳本、爬蟲、程序開發、科學計算,大數據,機器學習等。不一樣的場景下,使用的庫是有差別:windows

使用場景 經常使用庫
程序開發 flask/django
爬蟲 requests/beautifulsoup4/scrapy
科學計算 pandas/numpy/matplotlib
... ...

庫又會依賴另外的庫,這樣若是所有安裝在一個環境裏,難以規避庫的版本衝突。後端

鑑於python版本差別和使用場景差別,推薦使用虛擬環境進行隔離管理,省事很多。

怎麼使用虛擬環境

使用 pip

使用虛擬環境以前,咱們先花一點點時間來了解python的包安裝工具 pip , 相信我這很簡單。

Python的最大的優點之一是豐富的庫,跨平臺,在UNIX,Windows和Macintosh兼容很好。

安裝這些庫,讓開發速度飈起來,就須要使用 pip

下面使用pip安裝requests庫示例:

(py27studio) ➜  pytest pip install requests
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting requests
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f1/ca/10332a30cb25b627192b4ea272c351bce3ca1091e541245cccbace6051d8/requests-2.20.0-py2.py3-none-any.whl (60kB)
    100% |████████████████████████████████| 61kB 1.5MB/s
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.25,>=1.21.1 (from requests)
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/62/00/ee1d7de624db8ba7090d1226aebefab96a2c71cd5cfa7629d6ad3f61b79e/urllib3-1.24.1-py2.py3-none-any.whl (118kB)
    100% |████████████████████████████████| 122kB 1.5MB/s
Collecting certifi>=2017.4.17 (from requests)
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/56/9d/1d02dd80bc4cd955f98980f28c5ee2200e1209292d5f9e9cc8d030d18655/certifi-2018.10.15-py2.py3-none-any.whl (146kB)
    100% |████████████████████████████████| 153kB 287kB/s
Collecting idna<2.8,>=2.5 (from requests)
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB)
    100% |████████████████████████████████| 61kB 131kB/s
Installing collected packages: chardet, urllib3, certifi, idna, requests
Successfully installed certifi-2018.10.15 chardet-3.0.4 idna-2.7 requests-2.20.0 urllib3-1.24.1
複製代碼

從示例可見 pip 的2個特色:

  1. 快速安裝。命令行中一鍵安裝完成。

  2. 自動解決依賴。在安裝requests的同時還安裝了: chardet, urllib3, certifi, idna 而且自動解決各個庫的版本問題, 通常狀況下咱們不用關心這些細節。

下面是 pip的一些經常使用命令

# 列出庫列表
pip list
# 升級pip
pip install pip -U
# 安裝指定的庫
pip install name
# 刪除指定的庫 
pip uninstall name
複製代碼

瞭解 pip 的經常使用命令後,能夠愉快的寫代碼了。逐漸你會遇到在不一樣機器上同步庫或者同事使用你的代碼,須要安裝相同的庫。這時候你就須要pip的2個進階命令了。

# 將當期環境中的庫列表造成 requirements.txt 文件
pip freeze >requirements.txt
# 根據 requirements.txt 批量安裝庫
pip install -r requirements.txt
複製代碼

你可使用下面2個命令,獲取pip的使用幫助,瞭解更多

pip help
pip install -h
複製代碼

因爲PyPI服務位於國外,訪問起來比較緩慢,可使用國內的一些源進行加速

設置pip使用國內源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
複製代碼

一些其它的源: 豆瓣源:pypi.douban.com/simple/ 阿里雲源: mirrors.aliyun.com/pypi/simple…

其它平臺/語言也有相似的解決方案,若是你有興趣可使用下面關鍵字自行了解。

yum/apt/npm/brew/maven...

使用 venv

Python 從3.3 版本開始,自帶了一個虛擬環境 venv,在 PEP-405 中能夠看到它的詳細介紹。

在 *nix 系統上,能夠直接執行 pyvenv ./blog-env 來建立一個虛擬環境。在 Windows 系統上,則可使用 python -m venv ./blog-env 來建立, 這個命令也能夠用於 *nix 系統,推薦使用。

venv建立的虛擬環境,建議就在項目目錄,這樣使用起來更方便,沒有記憶負擔。

建立完成後 *nix 系統上, 使用 source ./blog-env/bin/activate 進入虛擬環境,window系統上,使用 Scripts\\activate.bat,效果以下:

➜  blog source ./blog-env/bin/activate
(blog-env) ➜  blog
複製代碼

注意在命令提示符以前新出現的 (blog-env) 標識進入了新的虛擬環境。

這樣很方便就得到了一個隔離的python環境。

使用 pipenv

pipenvKenneth Reitz推出的python包依賴工具, kr就是大名鼎鼎requests的做者。pipenv號稱Python Dev Workflow for Humans, 實力可見一斑。

介紹pipenv以前,咱們先看venv存在的問題。我這裏有一個django項目,使用django-rest-framework提供RestFul api服務, 利用jwt進行先後端認證,項目安裝完後依賴大概以下:

(wxsc) ➜  wordpress pip list
Package                 Version
----------------------- ----------
asn1crypto              0.24.0
certifi                 2018.10.15
cffi                    1.11.5
chardet                 3.0.4
coreapi                 2.3.3
coreschema              0.0.4
cryptography            2.3.1
diff-match-patch        20181111
Django                  2.0.5
django-crispy-forms     1.7.2
django-filter           2.0.0
django-formtools        2.1
django-import-export    1.1.0
django-reversion        3.0.0
djangorestframework     3.9.0
djangorestframework-jwt 1.11.0
et-xmlfile              1.0.1
future                  0.16.0
httpie                  1.0.0
httplib2                0.12.0
idna                    2.7
itypes                  1.1.0
jdcal                   1.4
Jinja2                  2.10
Markdown                3.0.1
MarkupSafe              1.1.0
odfpy                   1.3.6
openpyxl                2.5.10
pip                     18.1
pipenv                  2018.11.14
pycparser               2.19
Pygments                2.2.0
PyJWT                   1.6.4
PyMySQL                 0.9.2
pytz                    2018.5
PyYAML                  3.13
requests                2.20.1
setuptools              40.6.2
six                     1.11.0
tablib                  0.12.1
unicodecsv              0.14.1
uritemplate             3.0.0
urllib3                 1.24.1
virtualenv              16.1.0
virtualenv-clone        0.4.0
wheel                   0.32.2
xlrd                    1.1.0
XlsxWriter              1.1.2
xlwt                    1.3.0
複製代碼

前先後後大約安裝了50個包,最後徹底不清楚,那些是我直接安裝的,那些是間接安裝的,pipenv能夠解決這個問題。

pipenv 安裝很方便:

$ pip install pipenv
複製代碼

若是標準版本仍是python2.7,則可使用 pip3 install pipenv

pipenv使用起來也很方便。接下來咱們一塊兒瞭解這個過程。

建立一個新的工做目錄myproject,使用下面命令建立虛擬環境,建立完成後目錄下會生成一個Pipfile文件。

$ pipenv --three
Creating a virtualenv for this project…
Pipfile: /private/tmp/myproject/Pipfile
Using /Library/Frameworks/Python.framework/Versions/3.7/bin/python3 (3.7.1) to create virtualenv…
✔ Complete
Using base prefix '/Library/Frameworks/Python.framework/Versions/3.7'
New python executable in /Users/tu/codes/venv/myproject-7Ev2diGY/bin/python3
Also creating executable in /Users/tu/codes/venv/myproject-7Ev2diGY/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /Library/Frameworks/Python.framework/Versions/3.7/bin/python3
Virtualenv location: /Users/tu/codes/venv/myproject-7Ev2diGY
Creating a Pipfile for this project…
複製代碼

查看虛擬環境的實際目錄,瞭解python命令路徑(能夠用於配合pycharm選擇解釋器)。

$ pipenv --venv
$ pipenv --py
複製代碼

pipenv 的虛擬環境會統一存放,不會在項目路徑下

安裝軟件包。包安裝完成後,會在項目路徑下生成Pipfile.lock文件。

$ pipenv install requests
$ pipenv install django
複製代碼

注意: 這裏不是使用 pip 進行包安裝,而是使用 pipenv

查看項目依賴。視圖比較清晰的描述了,項目依賴了2個包,每一個包又分別依賴了其它的一些包。

➜  myproject2 pipenv graph
Django==2.1.3
  - pytz [required: Any, installed: 2018.7]
requests==2.20.1
  - certifi [required: >=2017.4.17, installed: 2018.10.15]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: >=2.5,<2.8, installed: 2.7]
  - urllib3 [required: >=1.21.1,<1.25, installed: 1.24.1]
複製代碼

重用requirements.txt文件。在項目目錄下建立requirements.txt,內容參見上文。

$ pipenv install
複製代碼

pipenv 默認會讀取本地目錄,也可使用**-r**參數指定requirements.txt位置。

pipenv 的依賴和 venv 有差別,可能直接導入 venv中的 requirements.txt 有一些問題,能夠直接手工安裝。

pipenv就簡單介紹到這裏,你們能夠看pipenv使用指南。總的來講venv和pipenv各有優點吧,venv原生自帶,簡單方便,比較適合服務器上調試;pipenv,功能強大更適合本地調試。

Anaconda

科學計算領域,python著名的庫pandasnumpymatplotlib, 而後還有圖像處理和視覺這塊的opencv,以及機器學習的tensorflow安裝比較複雜,在這個領域通常使用anaconda的解決方案,其wiki介紹以下:

Anaconda 是一種Python語言的免費增值開源發行版,用於進行大規模數據處理、預測分析,和科學計算,致力於簡化包的管理和部署。 Anaconda使用軟件包管理系統Conda進行包管理。

我選擇的是anaconda3,使用的iterm2,安裝完成後會有路徑問題,須要在~/.zshrc中添加:

export PATH="/anaconda3/bin:$PATH"
複製代碼

而後訪問使用下面命令查看anaconda環境。

➜  ~ which conda
/anaconda3/bin/conda
➜  ~ conda --version
conda 4.5.11
複製代碼

建立虛擬環境,並進入虛擬環境:

conda create --name python36 python=3.6
➜  ~ source activate python36
(python36) ➜  ~
(python36) ➜  ~ python -V
Python 3.6.7 :: Anaconda, Inc.
(python36) ➜  ~ source deactivate
➜  ~
複製代碼

查看conda管理的環境列表:

➜  ~ conda info -e
# conda environments:
#
base                  *  /anaconda3
python36                 /anaconda3/envs/python36
複製代碼

Anaconda在我的研發過程當中使用很少,若是想了解更多,能夠看Anaconda 入門安裝教程

docker時代的python環境

前面介紹的內容,都是在本地進行一些配置,建立各類環境。但是本地就一個,折騰幾回後仍是容易亂,docker這麼強大,咱們也能夠用docker來玩python開發。

首先,咱們編寫hello.py,代碼以下:

# -*- coding:utf-8 -*-


def test():
	print "Hello, python, docker"


if __name__ == "__main__":
	test()
複製代碼

而後執行下面命令:

docker run -it --rm --name docker-python2 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7.16-alpine3.9 python hello.py
複製代碼

命令結果以下:

Unable to find image 'python:2.7.16-alpine3.9' locally
2.7.16-alpine3.9: Pulling from library/python
8e402f1a9c57: Already exists
d8cdc394c05b: Pull complete
1e2b4a75cc6b: Pull complete
2fbbf60d928e: Pull complete
Digest: sha256:46d6e67d464a2811efe60440248623b14cb6db273fac59631dd8bd9e13a77491
Status: Downloaded newer image for python:2.7.16-alpine3.9
Hello, python, docker
複製代碼

注意,初次執行會進行鏡像文件下載,比較緩慢,下載成功後再次執行腳本就會很是迅速了。

這裏的docker命令比較複雜,能夠先不用管它的含義。咱們繼續編寫hello3.py,代碼以下:

# -*- coding:utf-8 -*-


def test():
	print("Hello, python, docker")


if __name__ == "__main__":
	test()
複製代碼

使用下面命令執行:

docker run -it --rm --name docker-python3 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:3.7.3-alpine3.9 python hello3.py
複製代碼

執行結果以下:

Unable to find image 'python:3.7.3-alpine3.9' locally
3.7.3-alpine3.9: Pulling from library/python
Digest: sha256:11568bb68bd375727e468ea5995f556139ff305eed9d8ee1d04b1a4a03a6486a
Status: Downloaded newer image for python:3.7.3-alpine3.9
Hello, python, docker
複製代碼

咱們簡單瞭解一下運行命令的含義:

➜  python docker run --help
Usage:	docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  -i, --interactive                    Keep STDIN open even if not attached
  ...
  --rm                             Automatically remove the container when it exits
  ...
  -t, --tty                            Allocate a pseudo-TTY
  ...
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified container(s)
  -w, --workdir string                 Working directory inside the container
複製代碼

docker run -it --rm --name docker-python2 -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:2.7.16-alpine3.9 python hello.py 翻譯過來的意思大概是下面幾點:

  1. 使用 python:2.7.16-alpine3.9 鏡像啓動容器,python表示鏡像名稱,2.7.16-alpine3.9表示版本標籤。
  2. 容器名稱命名爲docker-python2,而且輸出信息到當前終端,容器運行完成後自動刪除。
  3. 容器使用數據卷,將當前目錄和容器內的/usr/src/myapp目錄進行映射。
  4. 設置/usr/src/myapp爲工做目錄,而後運行python hello.py命令。

這樣通過上面幾步,咱們就使用docker容器執行了hello.py了。並且咱們也有了2個鏡像,能夠分別執行python2和python3的代碼。固然實際的工程中,只是執行一個py文件 有點殺雞用牛刀的感受,能夠若是執行一個django項目,倒是能夠很好的保持開發環境和部署環境的一致。這部份內容,之後我會進行補充介紹。

提示:docker和venv/pipenv也能夠配合使用,將虛擬環境建立在當前目錄便可,留給你們動手探索吧。

回顧

最後,咱們一塊兒來簡單回顧一下python虛擬環境:

  1. 使用python虛擬環境能夠有效解決python語法版本差別及使用場景差別。
  2. 使用pip安裝各類包。
  3. python3自帶venv建立和管理各類環境。
  4. pipenv是一種混合了pip和venv的環境管理方法。
  5. 使用anaconda管理python科學計算環境。
  6. 可使用docker等方式使用python環境。

附錄

若是繼續使用pyhon2,能夠參靠下面部份內容。python2的虛擬環境 virtualenv&virtualenvwrapper。

virtualenv 是一個建立隔絕的Python環境的工具,能夠建立一個包含全部必要的可執行文件的文件夾,用來使用Python工程所需的包。

virtualenv安裝很是簡單,直接使用下面命令:

pip install virtualenv
複製代碼

可能會遇到權限問題,可使用sudo提權

可是virtualenv有一個弊端是,每次會在當前目錄建立venv)(pycharm默認使用這種方式),每次須要本身記住不一樣的虛擬機目錄,使用起來不太方便。 這裏咱們直接跳過virtualenv的使用,繼續使用其擴展包virtualenvwrapper

virtualenvwrapper安裝也很是簡單,直接使用下面命令:

pip install virtualenvwrapper
複製代碼

! 注意:windows用戶使用的命令是 pip install virtualenvwrapper-win 後面帶**-win**

使用virtualenvwrapper須要先設置環境變量,我使用的iTerm2配置的zshrc,須要在用戶根目錄下的.zshrc中增長下面2行:

export WORKON_HOME=~/codes/venv
source /usr/local/bin/virtualenvwrapper.sh
複製代碼

配置好環境變量後,退出重啓term生效。

建立一個flask開發環境

mkvirtualenv flask
Using base prefix '/Library/Frameworks/Python.framework/Versions/2.7'
New python executable in /Users/tu/codes/venv/flask/bin/python
Also creating executable in /Users/tu/codes/venv/flask/bin/python
Installing setuptools, pip, wheel...done.
virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/predeactivate
virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/postdeactivate
virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/preactivate
virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/postactivate
virtualenvwrapper.user_scripts creating /Users/tu/codes/venv/flask/bin/get_env_details
(flask) ➜  pytest
複製代碼

注意建立好虛擬環境後會自動進入該環境,命令提示符前會顯示當前環境的名稱,例如(flask) 字樣。

再建立一個爬蟲的開發環境

mkvirtualenv spider
...
複製代碼

這樣你能夠在flask的環境中安裝flask庫,spider的環境中安裝requests庫,而不用擔憂依賴衝突。

若是你但願建立一個python3版本的環境,須要先行安裝好python3,而後使用下面命令:

# -p 參數指定版本,可使用python3的絕對路徑
mkvirtualenv py3studio -p python3
複製代碼

其它經常使用命令,以下:

# 列出env列表
workon
# 進入指定的env
workon name
# 退出當前env
deactivate
# 刪除env
rmvirtualenv name
複製代碼

ok,咱們使用pip安裝virtualenv和virtualenvwrapper,順利的解決了不一樣版本的python問題,能夠愉快的開發(玩耍)了。

相關文章
相關標籤/搜索