原本想在一篇之内覆盖到 Python 的包管理以及各类虚拟环境的应用,没想根本就是一发不可收拾,恐怕两篇都完不了,所以也要进行重构。这里只涉及到 Python 的虚拟环境 venv 和 virtualenv,至于标题的话,也不想再改了,只作一,二,三编号,必要时仍能连缀成长篇。最后一篇将单独学习 pipenv 的应用。

2. Python 虚拟环境

关于创建 Python 项目的虚拟环境,有三个工具可用, venv, virtualenv, 以及后面单独要学到的 pipenv

venv , 即 python3 -m venv 命令,Python 3.3 及新版本自带了,为 Python 3.4 及以后的版本创建的虚拟环境会有 pip 和 setuptools 命令

virtualenv 需要单独安装,但是它支持 Python 2.7 和  Python 3.3+, 创建的虚拟环境中带有 pip, setuptools 和 wheel 命令

另外,pyvenv 脚本也可用来创建 Python 虚拟环境,不过它自 Python 3.6 不推荐使用,建议用 python3 -m venv 命令

从以上几点来理解,virtualenv 可用于兼容 Python 2 和 3,如果只用到 Python 3.3 及以后的版本的话,推荐使用 python3 -m venv,实质上它们两都没多大的区别。下面分别看下 venv 和 virtualenv 的应用

2.1 venv(python3 -m venv)

venv 是以一个标准的 Python 模块来执行的,由于它在 Python 3.3+ 中自带了,所以不用安装。python3 -m venv 或 python3 -m venv -h 可以看到使用帮助,然后实际用来创建一个虚拟环境时,比如以下命令

python3 -m venv demo

可能就出现缺组件的提示,类似

vagrant@ubuntu-bionic:~$ python3 -m venv demo

The virtual environment was not created successfully because ensurepip is not

available. On Debian/Ubuntu systems, you need to install the python3-venv

package using the following command.

apt-get install python3-venv

You may need to use sudo with that command. After installing the python3-venv

package, recreate your virtual environment.

Failing command: ['/home/vagrant/demo/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']

那么就要安装 python3-venv

sudo apt-get install python3-venv

然后就能够

2.1.1 创建虚拟环境项目

python3 -m venv demo

创建 demo 项目,同时建立相应的  demo 目录,来了解一下该目录中有什么,见下图

python 查询虚拟环境 python查看虚拟环境列表_python查看虚拟环境列表

lib 中的目录层次是 lib/python3.6/site-packages/。从 bin 目录中看到有  pip 和  easy_install。所以这个 demo 目录俨然一个完整的 Python 运行环境,因而谓之虚拟环境。

2.1.2 激活虚拟环境

source bin/activate

python 查询虚拟环境 python查看虚拟环境列表_python查看虚拟环境列表_02

(demo) 提示当前激活了虚拟环境。bin/activate 为 bash 或 zsh 配置了基本的环境,如

命令提示符前加 (demo),

把 demo/bin 放在 PATH 的最前面,确保 pip, python 等命令默认是 demo/bin 下的相应命令

并创建 deactivate 函数用于退出虚拟环境

activate.csh 和 activate.fish 分别是为 csh 和 fish 服务的。且其中的 pip, pip3, pip3.6 可能完全是一回事,python 和 python3 也是一样的。

2.1.3 查看虚拟环境的 sys.path

在激活了虚拟环境后,执行 python3 -c "import sys; print(str(sys.path).replace(',', '\n'))"

1

2

3

4

5

[''

'/usr/lib/python36.zip'

'/usr/lib/python3.6'

'/usr/lib/python3.6/lib-dynload'

'/home/vagrant/demo/lib/python3.6/site-packages']

2.1.4 测试虚拟环境

pip install boto3

模块将安装到 /home/vagrant/demo/lib/python3.6/site-packages 中,根据前面的 sys.path 列表内容,boto3 可被该虚拟环境加载到。

在使用虚拟环境时切记不要用以下两条命令之一来安装模块

sudo pip install  boto3   # 可能找不到 pip 命令

pip install boto3 --user   # 加了 --user 参数模块会安装到 /home/vagrant/.local/lib/python3.6/site-packages 目录中,无法被虚拟环境加载到

这样安装的模块只对当前虚拟环境有效,既不影响当前用户,更不会污染到全局系统。

2.1.5 生成 requirements.txt 文件

安装了第三方模块后,可用命令 pip freeze 梳理出所有安装的第三方模块

1

2

3

4

5

6

7

8

9

10

11

(demo)vagrant@ubuntu-bionic:~/demo$pipfreeze>requirements.txt

(demo)vagrant@ubuntu-bionic:~/demo$catrequirements.txt

boto3==1.9.71

botocore==1.12.71

docutils==0.14

jmespath==0.9.3

pkg-resources==0.0.0

python-dateutil==2.7.5

s3transfer==0.1.13

six==1.12.0

urllib3==1.24.1

由于安装了 boto3 时也安装了它所依赖了其他包,其实这个 requirements.txt 只需要一行

boto3==1.9.71

就行,pip freeze 还不足够聪明只抓出所以最顶层的依赖。版本控制服务器上只要分享 requirements.txt 就行,其他人拿到这个文件,只需要用

pip install -r requirements.txt

安装其他描述的所有依赖。关于 requirements.txt 文件的格式请参考: Requirements File Formats。

2.1.6 退出虚拟环境

deactivate

python 查询虚拟环境 python查看虚拟环境列表_虚拟环境_03

2.2 virtualenv 命令

如果是 Python 3.3 以前的版本,需要单独安装 virtualenv 程序(模块)。安装命令如下:

sudo apt-get install virtualenv

或 pip install virtualenv

或 pip3 install virtualenv

第一种方式安装的 virtualenv 即是程序又是一个 Python 模块,也就是说可以用 virtualenv 或 python -m virtualenv 两种方式来运行,但它只支持 Python 2

第二第三种方式安装的 virtualenv 只是一个 Python 模块,只能以 python -m virtualenv 方式执行,或 python3 -m virtualenv

pip 安装的 virtualenv 创建的虚拟环境只支持 Python 2, pip3 安装的 virtualenv 创建的虚拟环境只支持 Python 3。如果创建 Python 2 的虚拟环境时系统中未安装 Python 2 会提示

vagrant@ubuntu-bionic:~$ virtualenv

The path python2 (from --python=python2) does not exist

vagrant@ubuntu-bionic:~$ python -m virtualenv

The path python2 (from --python=python2) does not exist

其他的用 virtualenv 创建虚拟环境,激活,使用,退出等与 venv 是一样的,不再累述了。

2.3 关于 Python 虚拟环境

创建 Python 虚拟环境是为了依赖相互隔离,并不需要为每一个 Python 项目创建独立的虚拟环境,就像多个系统用户可以共享全局环境,多个项目可以共享同一用户环境一样,多个 Python 项目也能共享同一个虚拟环境。比如两个非常类似的项目,它们所依赖的模块是一样的,它们就能用同一个虚拟环境。

如果虚拟环境就在项目目录中,那么其中包含的 bin, include, lib 目录在提交到版本控制系统上时就需要被忽略掉,例如用 .gitignore 文件来排除。此时应该用 requirements.txt 列出所有的依赖,并提交该文件到版本控制系统中去。这一点 pipenv 就更聪明一些了,它的虚拟环境目录与项目目录是分离的。

venv 与 virtualenv 基本上可以算是同一个东西吧,只是 Python 3.3+ 放到了标准库中,之前的版本才要单独安装,也就是 virtualenv。如果要用到 Python 3.3 之前的版本及 Python 2.7, 就必须用 virtualenv, 基本上只需 Python 3.3+ 的情况下用标准库中的 venv 就行。