纸上得来终觉浅,绝知此事要躬行。
1. 包管理
使用
Python
语言进行编程的时候,不可避免的需要安装和使用第三方的包,怎么样方便且易用对于我们来说就是一个很重要的事情了,下面就开始介绍几个对应对的工具。
[-] 安装第三方包的方法
- [推荐] 通过
Python
社区开发的pip
、easy_install
等工具 - [禁止] 使用系统本身自带的包管理器
yum
、apt-get
等 - [特定] 通过源码安装,如执行
python setup.py install
命令
- [推荐] 通过
[1] easy_install 工具
- 它是
setuptools
包里自带的一个命令,不用额外安装 - 使用它实际上是在调用
setuptools
来完成安装模块的工作` - 终端上的输出不够友好
- 安装的包不能缓存使用,每次都要下载甚至编译
- 不能集中管理项目依赖列表,就是包得一个一个安装
- 它提供的
Python
应用打包部署方式(egg
)已经落伍了 - 它只支持安装,没有提供卸载、展示当前已安装的包列表等功能
- 它是
[2] pip 工具的优势
- 更好的终端输出效果
- 它支持多种版本工具格式的包的下载和安装
- 它能非常好地支持虚拟环境
virtualenv
工具 - 它已经内置到
2.7.9
和3.4
及其以上的版本里面 - 它可以集中管理项目依赖列表,使用
-r
选项安装这些依赖 - 它支持二进制包使用
wheel
格式,而easy_install
不支持 - 它只支持安装,没有提供卸载、展示当前已安装的包列表等功能
- 可以对下载的包进行缓存,下次直接从缓存目录取而不需要下载了
# 使用pip工具安装
$ sudo apt-get install python-pip -yq
# 参数-q表示静默安装减少过程输出
$ sudo pip install pip -U -q
2. 虚拟环境工具
主要介绍我们在使用 Python 工具时使用到的虚拟环境工具
2.1 virtualenv
virtualenv
模块用于,在一台机器上创建多个Python
虚拟运行环境,多个Python
环境相互独立且互不影响,只是对固定版本Python
的一个复制,所以没有权限问题。
# 参数列表
$ virtualenv --help
Usage: virtualenv [OPTIONS] DEST_DIR
Options:
--version 显示程序的版本号并退出
-h, --help 显示此帮助消息并退出
-v, --verbose 输出详细信息
-q, --quiet 静默输出
-p PYTHON_EXE 要使用的Python解释器
--clear 清空非root用户的安装并重头开始创建隔离环境
--no-site-packages 令隔离环境不能访问系统全局的site-packages目录(默认)
--system-site-packages 令隔离环境可以访问系统全局的site-packages目录
--no-setuptools 不要在新的virtualenv中安装setuptools工具
--no-pip 不要在新的virtualenv中安装pip工具
--download 从PyPI下载预安装的包
--no-download 不要从PyPI下载预安装的包
--prompt=PROMPT 提供了一个可选的提示前缀环境
# 安装virtualenv工具
$ sudo pip install virtualenv
# 创建Python虚拟环境
$ virtualenv venv
New python executable in /home/escape/venv/bin/python
Installing setuptools, pip, wheel...done.
# 激活虚拟环境
$ source venv/bin/activate
(venv)$ which python
/home/escape/venv/bin/python
# 退出虚拟环境
(venv)$ deactivate
# 加上--no-site-packages参数; 得到干净的Python运行环境
# 这样已经安装到系统Python环境中的所有第三方包都不会复制过来
$ virtualenv --no-site-packages venv
# 创建不用版本的venv环境
# 可以配合pyenv来创建不同Python版本的运行环境
$ virtualenv -p `which python3.6` venv
$ virtualenv -p `which python3.6` --no-site-packages venv
2.2 venv
venv
模块是在Python3.3
中引入的一个创建虚拟环境的模块,它是经过virtualenv
改造进入的标准库的,主要用于创建虚拟环境。
# Python3.6开始pyvenv脚本已经不可用
$ pyvenv /path/to/new/virtual/environment
# Python3.6之后只能使用如下方式创建虚拟环境
$ python3 -m venv /path/to/new/virtual/environment
# 新版本使用操作步骤
$ python -m venv .env
$ source .env/bin/activate
$ pip install spacy
2.3 pyenv
pipenv
模块是Python
项目的依赖管理器,其实它并没有什么先进的理念或者技术,类似于Node.js
的npm
工具。虽然pip
可以安装Python
的第三方包,但是推荐使用pipenv
,因为它是一种更加高级的工具,可以简化依赖关系等优点。
# 一样进入虚拟环境
"[ -d `pipenv --venv` ] && source `pipenv --venv`/bin/activate && reset"
- pipenv
- [工具特点]
- 自动更新
pip
工具 - 自动管理
Pipfile
新安装和删除的包 - 根据
Pipfile
自动寻找项目根目录 - 如果
Pipfile
不存在,可以自动生成Pipfile
和Pipfile.lock
- 自动在项目目录的
.venv
目录创建虚拟环境,可通过设置WORKON_HOME
改变 - [基础理念]
pipenv
默认也包含了对.env
文件的支持- 提供版本锁支持,存为
Pipfile.lock
文件 Pipfile
文件是TOML
格式而不是requirements.txt
这样的纯文本- 一个项目对应一个
Pipfile
,支持开发环境与正式环境区分,默认提供default
和development
区分
#####################
# 以Mac下Python3为例 #
#####################
# 安装Python3版本
$ brew install python
$ python -m pip install --upgrade --force-reinstall pip --user
# 推荐安装在个人目录下
$ pip install pipenv --user
# 把用户目录下bin放在最前面,这样可以直接使用pipenv了
$ export PATH="/Users/Escape/Library/Python/3.7/bin:$PATH"
#################
# 使用pipenv工作 #
#################
# 创建一个工作目录
$ mkdir test_pipenv; cd test_pipenv
# 创建一个虚拟环境
$ pipenv install
......
Installing dependencies from Pipfile.lock (a65489)...
🐍 ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00
To activate this project virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
# 还是mac自带的Python
$ which python
# 激活虚拟环境
$ pipenv shell
# 已经在虚拟环境里了
$ which python
/Users/Escape/.local/share/virtualenvs/test_pipenv-wGd2NbSj/bin/python
# Pipfile用来保存依赖关系的
$ ll
total 16
-rw-r--r-- 1 Escape staff 138B 9 10 12:52 Pipfile
-rw-r--r-- 1 Escape staff 453B 9 10 12:52 Pipfile.lock
# 退出虚拟环境
$ exit
#################
# 使用pipenv工作 #
#################
# 安装2个包,分别为elasticsearch-dsl和requests库
# 现在Pipfile.lock已经更新了,包含了相关依赖的包信息
# 可添加--two或--three标志到下面的最后一个命令,分别使用Python2或3来初始化你的项目
$ pipenv install elasticsearch-dsl requests
# 可以看一下依赖关系
$ pipenv graph Escape@EscapeLife
elasticsearch-dsl==6.2.1
- elasticsearch [required: >=6.0.0,<7.0.0, installed: 6.3.1]
- urllib3 [required: >=1.21.1, installed: 1.23]
- ipaddress [required: Any, installed: 1.0.22]
- python-dateutil [required: Any, installed: 2.7.3]
- six [required: >=1.5, installed: 1.11.0]
- six [required: Any, installed: 1.11.0]
requests==2.19.1
- certifi [required: >=2017.4.17, installed: 2018.8.24]
- chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
- idna [required: >=2.5,<2.8, installed: 2.7]
- urllib3 [required: >=1.21.1,<1.24, installed: 1.23]
# 可以看到两者都依赖了urllib3
# 虽然现在pipenv不能直接卸载包及其依赖,但我们可以婉转的实现
$ pipenv uninstall `pipenv graph --json | python depends.py requests`
# 其中depends.py脚本会解析依赖关系,排除其他包依赖的项目然后删除
$ cat depends.py
import sys
import json
package = sys.argv[1]
other_dependencies = set()
removing_dependencies = set([package])
for i in json.load(sys.stdin):
for p in i['dependencies']:
key = p['key']
if i['package']['key'] == package:
removing_dependencies.add(key)
else:
other_dependencies.add(key)
print(' '.join(removing_dependencies - other_dependencies))
# 再看一下现在环境中的包依赖关系
$ elasticsearch-dsl==6.1.0
- elasticsearch [required: >=6.0.0,<7.0.0, installed: 6.1.1]
- urllib3 [required: >=1.21.1,<1.23, installed: 1.22]
- ipaddress [required: Any, installed: 1.0.19]
- python-dateutil [required: Any, installed: 2.6.1]
- six [required: >=1.5, installed: 1.10.0]
- six [required: Any, installed: 1.10.0]
###################
# pipenv的其他功能 #
###################
# 可以激活虚拟环境并使用shell命令
$ pipenv run which python
# 检查装的包的安全性
$ pipenv check
# 传统的看文档的方法
$ pipenv --man
# 代码Flake8检查
$ pipenv check --style depends.py
#################
# pipenv用法示例 #
#################
# Create a new project using Python 3.7, specifically:
$ pipenv --python 3.7
# Remove project virtualenv (inferred from current directory):
$ pipenv --rm
# Install all dependencies for a project (including dev):
$ pipenv install --dev
# Create a lockfile containing pre-releases:
$ pipenv lock --pre
# Show a graph of your installed dependencies:
$ pipenv graph
# Check your installed dependencies for security vulnerabilities:
$ pipenv check
# Install a local setup.py into your virtual environment/Pipfile:
$ pipenv install -e .
# Use a lower-level pip command:
$ pipenv run pip freeze
2.4 autoenv
autoenv
模块可以让你再切换文件目录的时候,自动激活和退出虚拟环境等一系列定制操作。虚拟环境的终极方案 = autoenv
+ pipenv
。
# 安装autoenv模块
$ sudo pip install autoenv
# 激活autoenv模块
$ source /usr/local/bin/activate.sh
# 创建项目目录
$ mkdir test
$ cd test
# 写autoenv的配置文件,需要使用绝对路径
$ touch .env
$ echo "source /home/escape/venv/bin/activate" > .env
# 重新进入该项目模块
$ cd ..
$ cd test
autoenv:
autoenv: WARNING:
autoenv: This is the first time you are about to source /home/escape/test/.env:
autoenv:
autoenv: --- (begin contents) ---------------------------------------
autoenv: source /home/escape/venv/bin/activate
autoenv:
autoenv: --- (end contents) -----------------------------------------
autoenv:
autoenv: Are you sure you want to allow this? (y/N) y
# 自动切换虚拟环境
(venv) $
3. 版本管理工具
如果你只单单使用
pyenv
的话,那么它就是一个版本管理工具而已。但是,如果配合上它相关的插件,那么简直就是神器,但有时会有Bug
需要自己处理,呜呜。
不推荐 pyenv 的理由
- 它用来解决切换
Python
版本问题,其实只不过是切换虚拟环境的另外一种途径,并没有存在的必要性 - 如果同
Python
版本多个虚拟环境情况它是没有办法解决的,还得用虚拟环境,不如一开始都统一用虚拟环境 Python
社区无感,它不是官方接受的解决方案,没有社区强力支持