目录

使用Pipenv管理Python项目

pip + pyvenv 方案的不足

  1. 手动更改版本包后,需要定期更新 requirements.txt 文件,以保持项目环境的一致。
  2. 项目中含有多个 requirement.txt 文件的,比如区分开发环境和生产环境,现有方案无法满足复杂需要;
  3. 卸载包的时候不能处理相关依赖包,造成包管理的混乱;

Pipenv

主要特性包含:

  1. Enables truly deterministic builds, while easily specifying only what you want.
  2. 为锁定的版本包生成并检查 hash,确保安全性;
  3. 如果 pyenv 可用,自动安装所需的 Pythons;
  4. 通过查找自动递归找到项目 Pipfile 文件(有点像 git);
  5. Pipfile 不存在时自动生成(类比 requirement.txt 是不是有很大的优势);
  6. 在指定位置自动创建虚拟环境;
  7. Pipfile 在卸载/安装软件包时自动添加/删除软件包。
  8. 自动加载 .env 文件,可以为项目设置环境变量(与 Flask 配合相当好用吧);

主要命令是 installuninstalllock

PS:Pipenv的作者是 Kenneth Reitz 大神,他写了 requests。

安装和配置

安装

通过 brew 安装(也可以通过 pip 安装):

1
brew install pipenv

配置

编辑 ~/.zshrc 文件

指定 virtualenv 存储路径

默认 virtualenv 都存储在 ~/.local/share/virtualenvs 目录下。

通过环境变量指定目录(最好使用绝对路径):

1
export WORKON_HOME=~/.venvs

如果要保存到项目目录下的 .venv 目录,设置:

1
export PIPENV_VENV_IN_PROJECT=true

基本操作

新建虚拟环境

使用 pipenv shellpipenv install 命令都能够自动触发创建虚拟环境。执行后会在目录中新建 PipfilePipfile.lock 文件,这两个文件要加入 VCS。

或者直接指定 Python 版本,配合 pyenv 使用效果更佳。

1
pipenv --python 3.7.1

安装软件包

安装指定包:

1
pipenv install xxx

安装 Pipfile 文件中指定的包:

1
pipenv install

以上两个命令都支持 --dev 选项,表示安装为开发环境使用的包。

另外,安装 Pipfile.lock 文件中指定的所有包:

1
pipenv sync

使用虚拟环境

进入虚拟环境

1
pipenv shell

退出虚拟环境

1
exit

使用虚拟环境执行命令,但不进入虚拟环境:

1
pipenv run python3

查看依赖关系

1
pipenv graph

输出

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
celery==4.0.2
  - billiard [required: <3.6.0,>=3.5.0.2, installed: 3.5.0.3]
  - kombu [required: >=4.0.2,<5.0, installed: 4.1.0]
    - amqp [required: >=2.1.4,<3.0, installed: 2.2.2]
      - vine [required: >=1.1.3, installed: 1.1.4]
  - pytz [required: >dev, installed: 2018.4]
PyMySQL==0.8.0
redis==2.10.6
requests==2.18.4
  - certifi [required: >=2017.4.17, installed: 2018.1.18]
  - chardet [required: >=3.0.2,<3.1.0, installed: 3.0.4]
  - idna [required: <2.7,>=2.5, installed: 2.6]
  - urllib3 [required: >=1.21.1,<1.23, installed: 1.22]
SQLAlchemy==1.2.6
tornado==4.3

还可以输出 json 格式

1
pipenv graph --json

卸载软件包

使用 uninstall 命令

1
pipenv uninstall xxx

但是该命令不会自动卸载软件包的依赖包,例如卸载 requests 时不会自动卸载 urllib3。

可以借助 graph 命令获得依赖关系并卸载

1
pipenv uninstall `pipenv graph --json | python3 depends.py requests`

其中 depends.py 用于解析依赖关系:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import sys
import json

package = sys.argv[1]
other_dependencies = set()
removing_dependencies = {package}

for i in json.load(sys.stdin):
    dependencies = {dependency['key'] for dependency in i['dependencies']}
    if i['package']['key'] == package:
        removing_dependencies.update(dependencies)
    else:
        other_dependencies.update(dependencies)

print(' '.join(removing_dependencies - other_dependencies))

检查安全问题

根据 PEP 508 检查当前管理的软件包版本是否存在漏洞

1
pipenv check

支持 .env 文件

Pipenv 在执行 pipenv runpipenv shell 命令时,如果在项目目录(即 Pipfile 的同级目录)下,存在 .env 文件,则会自动加载 .env 文件中的环境变量。

.env 文件不应加入到 VCS 中,因为它一般存储账号密码等关键保密信息。

参考链接