在开发多个python项目的时候,不同的项目可能要求的包(package)的版本不同,比如一个要求django1.2,一个要求django1.7。如果把很多不同版本的django都安装在系统全局的site-packages(有的系统上对应的是dist-packages])文件夹里,可能会造成冲突,将来处理这种系统层面的全局的冲突可能相当费劲。而且不同的项目要求使用的python版本也有可能不同,这种问题该如何解决?
virtualenv
virtualenv正是为了解决这个问题而生。使用virtualenv,开发者可以为每一个项目配置一个单独的虚拟开发环境,这个环境独立于系统全局的python环境。使用virtualenv为某个项目生成开发环境的时候,会把系统全局的python程序及其附带的pip和setuptools拷贝进这个环境。所以,各个项目都可以在自己的环境里根据需要使用pip命令安装需要的包(package)。
virtualenv的安装
安装环境
Mac OSX EI Captain,使用Homebrew安装的python版本及其附带的pip和setuptools工具,并且安装了Xcode7.3。
终端中执行
$ which python
终端输出的python执行程序位置是
/usr/local/bin/python
再看python版本:
$ python --version
终端输出版本信息如下:
Python 2.7.11
再看pip位置
$ which pip
可以看到pip位置如下:
/usr/local/bin/pip
安装步骤
执行以下指令安装:
$ pip install virtualenv
注意,不要使用sudo pip install virtualenv,会安装到系统级别的site-packages文件夹下,而不是homebrew版python2.7对应对的site-packages文件夹。安装成功,终端输出以下信息:
Collecting virtualenv
Downloading virtualenv-15.0.2-py2.py3-none-any.whl (1.8MB)
100% |████████████████████████████████| 1.8MB 207kB/s
Installing collected packages: virtualenv
Successfully installed virtualenv-15.0.2
You are using pip version 8.0.2, however version 8.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
建立保存项目虚拟环境的文件夹,我选择了放在HOME目录下(当然你也可以放在任何自己喜欢的其它地方):
$ mkdir -p ~/ProjectsEnv
进入刚刚创建的文件夹中
$ cd ~/ProjectsEnv
假设有一个python项目名为engchen,给这个项目新建一个对应的名为engchen的开发环境:
$ virtualenv engchen
注意,使用这个命令安装了会把python的全局(global)site-packages安装到虚拟环境中,可以在命令末尾加一个参数禁止把全局的site-packages文件安装到虚拟环境中,格式如下:
$ virtualenv engchen --no-site-packages
更正: virtualenv1.7版本后执行virtualenv engchen命令默认是带这个参数的.
安装成功,终端输出以下信息:
New python executable in /Users/chenxin/ProjectsEnv/engchen/bin/python2.7
Also creating executable in /Users/chenxin/ProjectsEnv/engchen/bin/python
Installing setuptools, pip, wheel...done.
如果不想使用这个Homebrew安装的python2.7版,比如使用苹果系统自带的python2.6,可以在生成开发环境时指定python2.6的bin路径,系统自带的python2.6版本位于/usr/bin/python2.6,那么对应的指令就是
$ virtualenv -p /usr/bin/python2.6 engchen
如果想要配置这个python虚拟开发环境,需要执行
$ source engchen/bin/activate
终端会变成这个样子:
MacBookPro:ProjectsEnv chenxin$ source engchen/bin/activate
(engchen) MacBookPro:ProjectsEnv chenxin$
注意发生了什么!终端提示(shell prompt)前面多了虚拟环境的名字engchen。virtualenv官方文档给出了这样的解释:
This will change your $PATH so its first entry is the virtualenv’s bin/ directory. (You have to use source because it changes your shell environment in-place.) This is all it does; it’s purely a convenience. If you directly run a script or the python interpreter from the virtualenv’s bin/ directory (e.g. path/to/ENV/bin/pip or /path/to/ENV/bin/python-script.py) there’s no need for activation.
The activate script will also modify your shell prompt to indicate which environment is currently active. To disable this behaviour, see VIRTUAL_ENV_DISABLE_PROMPT.
大意是activate脚本对系统的PATH变量执行了操作,使得虚拟环境里的bin文件夹里的指令优先执行,同时修改了shell prompt用以提示用户正在哪一个环境下进行操作。
注意: 本文之后的命令都是在shell prompt内容为(engchen) MacBookPro:ProjectsEnv chenxin$的环境下执行的。
先来看看这时的python执行程序位置:
$ which python
可以看到python位于
/Users/chenxin/ProjectsEnv/engchen/bin/python
再来看看pip位置:
$ which pip
可以看到pip位于
/Users/chenxin/ProjectsEnv/engchen/bin/pip
假如我想把python爬虫框架scrapy安装到这个环境,只需执行:
$ pip install scrapy
安装失败,终端输出以下信息:
Building wheels for collected packages: cssselect, PyDispatcher, lxml, Twisted, pycparser
Running setup.py bdist_wheel for cssselect ... done
Stored in directory: /Users/chenxin/Library/Caches/pip/wheels/1b/41/70/480fa9516ccc4853a474faf7a9fb3638338fc99a9255456dd0
Running setup.py bdist_wheel for PyDispatcher ... done
Stored in directory: /Users/chenxin/Library/Caches/pip/wheels/86/02/a1/5857c77600a28813aaf0f66d4e4568f50c9f133277a4122411
Running setup.py bdist_wheel for lxml ... error
......
......
In file included from src/lxml/lxml.etree.c:320:
src/lxml/includes/etree_defs.h:14:10: fatal error: 'libxml/xmlversion.h' file not found
#include "libxml/xmlversion.h"
^
1 error generated.
Compile failed: command 'clang' failed with exit status 1
creating var
creating var/folders
creating var/folders/pz
creating var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn
creating var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T
cc -I/usr/include/libxml2 -I/usr/include/libxml2 -c /var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/xmlXPathInity8Je15.c -o var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/xmlXPathInity8Je15.o
/var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/xmlXPathInity8Je15.c:1:10: fatal error: 'libxml/xpath.h' file not found
#include "libxml/xpath.h"
^
1 error generated.
*********************************************************************************
Could not find function xmlCheckVersion in library libxml2\. Is libxml2 installed?
Perhaps try: xcode-select --install
*********************************************************************************
error: command 'clang' failed with exit status 1
----------------------------------------
Failed building wheel for lxml
......
......
Successfully built cssselect PyDispatcher Twisted pycparser
Failed to build lxml
Installing collected packages: cssselect, queuelib, six, w3lib, lxml, parsel, PyDispatcher, zope.interface, Twisted, enum34, ipaddress, idna, pycparser, cffi, pyasn1, cryptography, pyOpenSSL, attrs, pyasn1-modules, service-identity, scrapy
Running setup.py install for lxml ... error
......
......
----------------------------------------
Command "/Users/chenxin/ProjectsEnv/engchen/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/private/var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/pip-build-YHuFxD/lxml/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/pip-U7InUV-record/install-record.txt --single-version-externally-managed --compile --install-headers /Users/chenxin/ProjectsEnv/engchen/bin/../include/site/python2.7/lxml" failed with error code 1 in /private/var/folders/pz/1sq2sn2922d0bzrpycsht1d40000gn/T/pip-build-YHuFxD/lxml/
经过一番搜索,参照了stackoverflow上的这个问题:Cannot install Lxml on Mac os x 10.9,得票最高的答案是使用xcode-select --install命令安装xcode命令行工具,可是笔者计算机明明安装了Xcode啊,抱着疑惑的态度还是执行了一下命令:
$ xcode-select --install
选择安装,安装完成后再执行
$ pip install scrapy
竟然神奇的安装好了!
查看安装的Package
执行
$ pip freeze
可以看到终端输出刚刚安装的Scrapy及其依赖:
attrs==16.0.0
cffi==1.6.0
cryptography==1.4
cssselect==0.9.1
enum34==1.1.6
idna==2.1
ipaddress==1.0.16
lxml==3.6.0
parsel==1.0.2
pyasn1==0.1.9
pyasn1-modules==0.0.8
pycparser==2.14
PyDispatcher==2.0.5
pyOpenSSL==16.0.0
queuelib==1.4.2
Scrapy==1.1.0
service-identity==16.0.0
six==1.10.0
Twisted==16.2.0
w3lib==1.14.2
zope.interface==4.2.0
最后,别忘了生成requirements.txt文件,根据这个文件可以在另一台机器上快速生成完全一样的开发环境。
根据环境生成requirements.txt文件的方法是:
$ pip freeze > requirements.txt
注意: 执行前面一条命令的时候必须先进入engchen问价夹:
$ cd engchen
否则生成的requirements.txt文件是在ProjectsEnv文件夹中的,而不是在engchen文件夹中。
将来使用生成requirements.txt文件恢复开发环境的只需要执行
$ pip install -r requirements.txt
退出虚拟环境
配置完虚拟python开发环境以后自然是要推出了,先执行
$ deactivate
之后就可以像平常一样操作了。
网友评论