原本想在一篇之内覆盖到 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 目录,来了解一下该目录中有什么,见下图
lib 中的目录层次是 lib/python3.6/site-packages/。从 bin 目录中看到有 pip 和 easy_install。所以这个 demo 目录俨然一个完整的 Python 运行环境,因而谓之虚拟环境。
2.1.2 激活虚拟环境
source bin/activate
(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
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 就行。