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问题,能够愉快的开发(玩耍)了。

相关文章
相关标签/搜索