python建立虚拟环境virtualenv

和其他大多数现代编程语言一样,Python对包和模块的下载、存储以及管理有其自己的一套方法。Python的包一般存在几个地方。比如,大部分系统包会存在sys.prefix指定的路径下。在Mac OS X下这个路径为:

import sys
sys.prefix'/System/Library/Frameworks/Python.framework/Versions/3.5''

通常情况下我们更关心第三方包的安装位置,比如easy_install或pip会将包存放在 site.getsitepackages所指定的路径下:

这里就带来了一个问题,当我们同时开发多个工程时,不同的工程会将第三方的包存放在相同的路径下。这就意味着,如果有两个工程依赖同一个包,但是所需要的版本却不一样,比如工程A依赖v1.0.0,而工程B依赖v2.0.0。由于Python无法根据版本来区分包的安装路径,所以这里就会发生版本冲突。这也就是本文所要介绍的虚拟环境(virtualenv/venv)所要解决的问题。

什么是虚拟环境?

Python虚拟环境的主要目的是为了给不同的工程创建互相独立的运行环境。在虚拟环境下,每一个工程都有自己的依赖包,而与其它的工程无关。不同的虚拟环境中同一个包可以有不同的版本。并且,虚拟环境的数量没有限制,我们可以轻松地用virtualenv或者pyenv等工具来创建多个虚拟环境.

虚拟环境的使用

安装虚拟环境工具的方法非常简单,

$ pip install virtualenv

然后,我们创建一个名字叫“env”的虚拟环境:

$ virtualenv env

这条命令会自动创建一个叫“env”的目录,并在其中生成如下的目录结构:

├── bin│ ├── activate│ ├── activate.csh│ ├── activate.fish│ ├── easy_install│ ├── easy_install-3.5│ ├── pip│ ├── pip3│ ├── pip3.5│ ├── python -> python3.5│ ├── python3 -> python3.5│ └── python3.5 -> /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5├── include├── lib│ └── python3.5│ └── site-packages└── pyvenv.cfg

这些目录包括:

bin: 用于管理虚拟环境的文件include: 编译Python包时所需要的C头文件lib: Python自带及第三方的库这其中还包含有一些Python的工具和可执行文件等副本。这些文件用来保证Python代码可以独立于系统环境而运行。

bin目录下有一个重要的脚本文件activate,这个脚本就是用来将其所在的虚拟环境设置为当前Python的运行环境:

$ source env/bin/activate(env) $

可以看到,在运行完这行命令后,shell的提示符前会出现虚拟环境的名字,表示我们已经进入了这个环境中。

为了验证这一点,我们以bcrypt模块为例。首先我们要在全局系统环境中安装这个模块。在测试之前,我们需要先通过deactivate命令退出当前的虚拟环境:

(env) $ deactivate$

现在我们的shell提示符回归到了正常状态,同时Python的环境也切换到了全局的系统环境。

现在我们来安装bcrypt并用它来生成一个密码的hash值:

$ pip -q install bcrypt$ python -c "import bcrypt; print(bcrypt.hashpw('password'.encode('utf-8'), bcrypt.gensalt()))"$2b$12$vWa/VSvxxyQ9d.WGgVTdrell515Ctux36LCga8nM5QTW0.4w8TXXi

然后我们切换到虚拟环境并试图运行同样的命令:

$ source env/bin/activate(env) $ python -c "import bcrypt; print(bcrypt.hashpw('password'.encode('utf-8'), bcrypt.gensalt()))"Traceback (most recent call last):File "<string>", line 1, in <module>ImportError: No module named 'bcrypt'

可以看到,在虚拟环境中,bcrypt并没有被安装,说明虚拟环境的隔离作用是生效的。

虚拟环境是如何工作的?

了解虚拟环境背后的工作原理,对于一个Python开发者来说非常重要,它能够帮助我们理解Python的运行环境,对依赖的解析等技术。为了解释虚拟环境的原理,我们先来看一下在不同的环境中,Python可执行文件的位置有什么不同。在默认的系统环境中查看python的路径:

$ which python/usr/bin/python

然后我们进入虚拟环境

$ source env/bin/activate(env) $ which python/Users/michaelherman/python-virtual-environments/env/bin/python

可以看到,在激活虚拟环境后,python可执行文件的路径变成了当前环境目录下的路径,并且$PATH也发生了变化:

$ echo $PATH/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$ source env/bin/activate(env) $ echo $PATH/Users/michaelherman/python-virtual-environments/env/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:

虚拟环境下的bin目录排在了$PATH的最前面。这意味着,用户在命令行中执行python的时候,将率先使用虚拟环境下的可执行文件,而不是系统默认的。

那么虚拟环境下的python可执行文件与系统默认的有什么不同呢?Python又是如何找到虚拟环境下的第三方库的呢?

事实上,上面提到的python可执行文件之间并没有什么不同,但是它们所在的位置至关重要。在Python启动的时候,它会获取自身所在的路径。然后这一路径(bin的上一级)被设置到sys.prefix和sys.exec_prefix之中。在搜索第三方的site-packages时,搜索目录是sys.prefix所指向的路径下的lib/pythonX.X/site-packages/,其中X.X是Python的版本。

在前面的例子中,python文件所在路径为/Users/michaelherman/python-virtual-environments/env/bin,因此sys.prefix会被设为/Users/michaelherman/python-virtual-environments/env,从而site-packages的路径就变成了/Users/michaelherman/python-virtual-environments/env/lib/pythonX.X/site-packages。最后,这一路径被存储在sys.path数组中,其中包含着所有包的引用来源。

使用virtualenvwrapper管理虚拟环境(推荐)

虚拟环境的引入解决了我们关于环境冲突的问题,但是它同时也带来了一个问题,就是虚拟环境过多所带来的管理问题。virtualenvwrapper就是专门用来解决虚拟环境管理问题的一个工具。我们可以很方便地用它来实现对虚拟环境的创建,删除,拷贝,并且可以轻松地在不同环境间进行切换。

virtualenvwrapper的安装非常简单:

$ pip install virtualenvwrapper

安装后,我们需要将virtualenvwrapper.sh脚本添加到shell启动文件中:

$ which virtualenvwrapper.sh/usr/local/bin/virtualenvwrapper.sh在shell启动文件~/.bashrc中添加:export WORKON_HOME=$HOME/.virtualenvs # Optionalexport PROJECT_HOME=$HOME/projects # Optionalsource /usr/local/bin/virtualenvwrapper.sh

并运行

$ source ~/.bashrc

然后就会在$WORKON_HOME所在的路径下创建集中存放虚拟环境的目录。

接着,我们就可以用下面的一系列命令虚拟环境进行管理:

workondeactivatemkvirtualenvcdvirtualenvrmvirtualenv

比如,我们要创建一个新的工程:

$ mkvirtualenv my-new-project(my-new-project) $

此时会在$WORKON_HOME下创建一个新的虚拟环境。

退出一个虚拟环境的方法和之前一样:

(my-new-project) $ deactivate$

如果你有多个虚拟环境,可以对它们进行查看:

$ workonmy-new-projectmy-django-projectweb-scraper

并选择其中一个进行激活:

$ workon web-scraper(web-scraper) $

这样,你就不再需要记住每一个环境存放的具体位置,可以轻松的对他们进行删除、拷贝、切换,是不是非常方便?

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值