12. 虚拟环境和软件包

12.1. 引言

Python程序会经常使用包和模块,它们不是标准库的一部分。程序有时会需要一个库的明确版本,因为程序可能要求某个特定的bug已经修掉,或者程序可能使用一个废弃的库的接口编写。

这意味着安装一个Python不可能满足每个程序的需要。如果程序A需要一个特定模块的1.0版本,但是程序B需要2.0版本,那么这个需求有冲突并且安装1.0或2.0都会导致一个程序不能运行。

解决这个问题的办法是创建一个虚拟环境(经常缩写为“virtualenv”),一个自包含的目录树,包含特定版本的Python以及很多额外的软件包。

然后,不同的程序可以使用不同的虚拟环境。为了解决先前的冲突要求的例子,程序A可以拥有自己的1.0安装版本的虚拟环境,同时程序B有另一个2.0版本的虚拟环境。如果程序B需要升级到3.0版本的库,这将不会影响到程序A的环境。

12.2. 创建虚拟环境

创建和管理虚拟环境的脚本被称为pyvenvpyvenv通常安装最新版本的Python;这个脚本安装的时候带有一个版本号,所以如果你的系统上有多个版本的Python,你可以通过运行pyvenv-3.4或你想要的版本来选择的一个特定的Python版本。

要创建一个虚拟环境,先决定好你想要放置的目录,然后以这个目录路径运行pyvenv

pyvenv tutorial-env

它将创建一个tutorial-env目录,如果不存在的话,它还会在这个目录下面创建包含Python解释器、标准库和各种支持文件的子目录。

一旦你创建好了一个虚拟环境,你需要激活它。

在Windows上,运行:

tutorial-env/Scripts/activate

在Unix或MacOS上,运行:

source tutorial-env/bin/activate

(这个脚本是用bash shell编写的。如果你使用的是csh或者fishshells,你应该使用activate.cshactivate.fish脚本)。

激活虚拟环境将改变你的shell提示符以显示你正在使用的虚拟环境,它还会修改环境变量使得运行python将得到特定版本的Python。例如:

-> source ~/envs/tutorial-env/bin/activate
(tutorial-env) -> python
Python 3.4.3+ (3.4:c7b9645a6f35+, May 22 2015, 09:31:25)
  ...
>>> import sys
>>> sys.path
['', '/usr/local/lib/python34.zip', ...,
'~/envs/tutorial-env/lib/python3.4/site-packages']
>>>

12.3. 用pip管理软件包

一旦你已经激活了虚拟环境,就可以使用称为pip 的程序安装、升级和移除软件包。pip会默认从Python包索引<https://pypi.python.org/pypi>安装包。你可以通过Web浏览器浏览Python包索引,或者可以使用pip有限的搜索功能:

(tutorial-env) -> pip search astronomy
skyfield               - Elegant astronomy for Python
gary                   - Galactic astronomy and gravitational dynamics.
novas                  - The United States Naval Observatory NOVAS astronomy library
astroobs               - Provides astronomy ephemeris to plan telescope observations
PyAstronomy            - A collection of astronomy related tools for Python.
...

pip有许多子命令:“search”、“install”、“uninstall”、“freeze”等。pip的完整文档请参考安装Python模块指南)。

你可以通过制定一个包的名称来安装最新版本的包:

-> pip install novas
Collecting novas
  Downloading novas-3.1.1.3.tar.gz (136kB)
Installing collected packages: novas
  Running setup.py install for novas
Successfully installed novas-3.1.1.3

你还可以通过给出包的名称后面跟着==和版本号来安装一个特定版本的包。

-> pip install requests==2.6.0
Collecting requests==2.6.0
  Using cached requests-2.6.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.6.0

如果你重新运行这个命令,pip将注意到要求的版本已经安装,从而什么也不做。你可以提供一个不同的版本来获得这个版本,或者你可以运行pip install --upgrade来升级包到最新的版本:

-> pip install --upgrade requests
Collecting requests
Installing collected packages: requests
  Found existing installation: requests 2.6.0
    Uninstalling requests-2.6.0:
      Successfully uninstalled requests-2.6.0
Successfully installed requests-2.7.0

pip uninstall后面跟随一个或多个包的名称将从虚拟环境中删除这些包。

pip show将显示一个特定的包的信息:

(tutorial-env) -> pip show requests
---
Metadata-Version: 2.0
Name: requests
Version: 2.7.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: me@kennethreitz.com
License: Apache 2.0
Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
Requires:

pip list将显示虚拟环境中安装的所有的包:

(tutorial-env) -> pip list
novas (3.1.1.3)
numpy (1.9.2)
pip (7.0.3)
requests (2.7.0)
setuptools (16.0)

pip freeze将产生一个已经安装的包的一个类似的列表,但是输出使用pip install期望的格式。常见的习惯是将这个列表放入一个requirements.txt文件:

(tutorial-env) -> pip freeze > requirements.txt
(tutorial-env) -> cat requirements.txt
novas==3.1.1.3
numpy==1.9.2
requests==2.7.0

requirements.txt可以用来做版本控制并作为程序的一部分。用户可以使用install -r安装所有必要的包:

-> pip install -r requirements.txt
Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
  ...
Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
  ...
Collecting requests==2.7.0 (from -r requirements.txt (line 3))
  ...
Installing collected packages: novas, numpy, requests
  Running setup.py install for novas
Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0

pip还有更多的选项。pip的完整文档请参考安装Python模块指南。当你编写完一个包并想让它在Python包索引上可以访问,请参考发布Python模块的指南。