本文主要内容参考自:

http://toomuchdata.com/2012/06/25/how-to-install-python-2-7-3-on-centos-6-2/#comment-5691

使用 Python,一个绕不过去的问题,就是其版本繁多的问题。首先是版本选择问题,这个不在我们讨论的范围之内,官网上在显眼的位置做了一些说明和建议:Python2 or Python3。

这里我们假设知道自己该选哪个或哪几个版本了。这里就会遇到第二个问题,Python 在 linux 中属于基础组件,各发行版会默认安装一个 Python,例如 CentOS5.5 中的是 2.4.3,而CentOS6.2 中是 2.6.6。

以 CentOS6.2 为例,在 /usr/bin 目录下有一个 Python 和一个 Python2.6。这两者有什么区别呢:

>[root@vps1 ~]# ls   -l /usr/bin/python  
-rwxr-xr-x 2 root root 3592 Dec  7  2011 /usr/bin/python
[root@vps1 ~]# ls   -l /usr/bin/python2.6 
-rwxr-xr-x 2 root root 3592 Dec  7  2011 /usr/bin/python2.6  

可以看到两个都不是软链接。通过计算一下 md5 值,可以发现这两者一模一样。

因此,/usr/bin/python 实际上是 /usr/bin/python2.6 的一个拷贝。如果我们此时想安装一个 python3.3,应该怎么做呢?首先绝对不要想着先去卸载已有的 Python,曾经 apt-get remove python 或者 yum remove python 的人肯定会会心一笑。最通常的做法,下载到 python3.3的源码来编译。

在 CentOS 下,通过 ./configure&&make&&make install 安装后,Python 会被安装到 /usr/local/bin 目录下,可能同时有 python、python3、python3.3。其中 python3.3 和 python 是两个一模一样h的可执行文件,而 python3 则是一个指向 /usr/local/bin/python 的软链接。这样带来的问题是,在 /usr/bin 和 /usr/local/bin 目录下,都有一个名为 python 的可执行文件。虽然通过环境变量的可以确定在 shell 中执行 python 时到底是执行了哪个目录下的 python,但总归显的很麻烦,时间长了更容易引起混乱。

这个仅仅是安装一个 Python 时遇到的问题,现实情况下,你可能同时跑着两个版本的 Django,每个版本的 Django 依赖的 Python 又不同,通过分别指定路径、建立软连接等方式虽然能解决,但还是一个字,乱。不知什么时候,就会互相影响了。

自从有了 virtualenv,pythoner 的生活就好起来了。

virtualenv 的目的就是让每个 Python 应用程序和自己依赖的 Python 解释器及 Python 库,各自隔离开来,互相不影响,更不会破坏系统自带的 Python 环境。

下面就来详细的演示 virtualenv 的操作过程:

1. 系统环境说明

操作系统:CentOS6.2  
\# cat /etc/issue  
CentOS release 6.2 (Final)  
Kernel \r on an \m  

系统自带python环境:

>\# python -V  
Python 2.6.6  
|# whereis python  
python: /usr/bin/python /usr/bin/python2.6 /usr/lib/python2.6 /usr/include/python2.6 /usr/share/man/man1/python.1.gz  
\# ls -l /usr/bin/python*  
-rwxr-xr-x 2 root root 3592 Dec  7  2011 /usr/bin/python  
lrwxrwxrwx 1 root root    6 Nov 12 06:29 /usr/bin/python2 -> python  
-rwxr-xr-x 2 root root 3592 Dec  7  2011 /usr/bin/python2.6  

2. 操作预期

分别安装最新版的 python2.7 和 python3.3,并各自安装一个 flask 框架,互相隔离。

3. 操作过程

(1)方便起见,首先安装一些其它常用的组件:

yum groupinstall "Development tools"  
yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel  

(2)下载和安装 python2.7.6

# mkdir -p /home/fangpeng/sources  
# cd /home/fangpeng/sources/  
# wget http://www.python.org/ftp/python/2.7.6/Python-2.7.6.tgz  
#tar xvfz Python-2.7.6.tgz  
#cd Python-2.7.6  
# ./configure --prefix=/usr/local  
# make && make altinstall  

注意,是 make altinstall,而不是 make install。这样可以避免造成系统存在多个名为 Python,实际版本却各异的文件。安装完毕后,/usr/bin 下系统自带的几个 Python 文件都没有任何影响。在 /usr/local/bin 目录下,则多了一个 python2.7 和 python2.7-config。

(3)下载和安装 python3.3.2

# cd /home/fangpeng/sources  
# wget http://www.python.org/ftp/python/3.3.2/Python-3.3.2.tgz  
#tar xvfz Python-3.3.2.tgz  
# cd Python-3.3.2  
# ./configure --prefix=/usr/local  
# make && make altinstall  

同样注意,是 make altinstall,而非 make install。安装完成后,在 /usr/local/bin 目录下,多出三个文件,分别是 python3.3m、python3.3 和 python3.3-config,其中 python3.3 和 python3.3m 是同一个文件的两份拷贝。对系统自带的 python2.6.6 和上一步安装的 python2.7.6 无影响。

(4)下载 distribute

# cd /home/fangpeng/sources  
# wget --no-check-certificate https://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz  

(5)为 python2.7.6 安装 easy_install

# tar xvfz distribute-0.6.49.tar.gz  
# cd distribute-0.6.49  
# python2.7 setup.py  install  

(6)为 python3.3.2 安装easy_install

# cd /home/fangpeng/sources/  
# rm -rf distribute-0.6.49  
# tar xvfz distribute-0.6.49.tar.gz  
# cd distribute-0.6.49  
# python3.3 setup.py install  

执行完(5)和(6)后,在 /usr/local/bin 目录下,会多出三个文件,分别是 easy_install、easy_install-2.7和easy_install-3.3。其中,easy_install 在两次安装时都会生成,因此会存在覆盖。我们直接使用 easy_install-2.7 和 easy_install-3.3 即可。

(7)为 python2.7 安装 virtualenv

终于到了virtualenv了,这才是我们今天的主角。

easy_install-2.7 virtualenv  

(8)为 python3.3 安装 virtualenv

easy_install-3.3  virtualenv  

至此,我们分别为 python2.7.6 和 python3.3.2 安装了 virtualenv。同样在 /usr/local/bin 目录下多出了三个文件,分别是 virtualenv、virtualenv-2.7 和 virtualenv-3.3。其中,virtualenv 在两次安装时都会生成,因此会存在覆盖。我们直接使用 virtualenv-2.7 和 virtualenv-3.3 即可。

下面用 web 框架 flask 的安装,来演示 virtualenv 的使用。创建两个 flask 的沙盒,其中一个依赖的是 python2.7.6,另一个依赖 python3.3.2。

(1)创建相应的工程目录

# mkdir -p /home/fangpeng/project/hello_flask  
# cd /home/fangpeng/project/hello_flask/  
# mkdir python2.7 python3.3  

(2)创建基于 python2.7 的 flask 工程

# cd /home/fangpeng/project/hello_flask/python2.7/  
# virtualenv-2.7 --distribute env  
Using base prefix '/usr/local'  
New python executable in env/bin/python3.3  
Also creating executable in env/bin/python  
Installing Setuptools..................................................................................................................................done.  
Installing Pip.............................................................................................................................................done.  
# source env/bin/activate  
(env)# 
(env)# python -V  
Python 2.7.6  
# pip install flask  
(env)# vim hello.py  

hello.py 内容如下:

from flask import Flask  
app=Flask(__name__)  
  
@app.route('/hello')  
def hello():  
        return "Hello,Flask!"  
if __name__=='__main__':  
        app.run(host='0.0.0.0',debug=True)  

执行hello.py:

(env)# python hello.py 
 * Running on http://0.0.0.0:5000/  
 * Restarting with reloader  

用浏览器或在另一个终端用 curl 访问该 hello 接口,如下:

# curl 192.168.1.101:5000/hello  
Hello,Flask!#  

(3)退出 python2.7 的 virtualenv 环境

继续上一步,按 ctr+c 退出 hello.py 的执行。如下所示,此时还处于 python2.7 的 virtualenv 中,执行 deactivate 退出。

(env)# deactivate  
# 

(4)创建基于 python3.3 的 flask 工程

#cd /home/fangpeng/project/hello_flask/python3.3/  
# virtualenv-3.3 --distribute env  
Using base prefix '/usr/local'  
New python executable in env/bin/python3.3  
Also creating executable in env/bin/python  
Installing Setuptools.........................................................................................done.  
Installing Pip....................................................................................................done.  
# source env/bin/activate  
(env)# 
#(env) python -V  
Python 3.3.2  
(env)# pip  install flask  

hello.py 的内容和上面完全一致,此处略去。

执行hello.py:

(env)# python hello.py 
 * Running on http://0.0.0.0:5000/  
 * Restarting with reloader  

用浏览器或在另一个终端用 curl 访问该 hello 接口,如下:

# curl 192.168.1.101:5000/hello  
Hello,Flask!#  

至此演示完毕。

与上面的例子类似,以后如果要 python2.7.6,则在创建应用程序前,先用 virtualenv-2.7 创建一个沙盘,要用 python3.3.2,则用 virtualenv-3.3 创建一个沙盘。这样,依赖不同版本 Python 的应用程序彼此完全隔离开来。在各自的 virtualenv 中,执行 Python 命令就不用管版本问题了,系统自带的 Python 环境也完全被隔离开来。