# 0x00 前言

PyCon 2018 有很多精彩的演讲,今天的文章里,介绍一下 K 神的演讲 『Python 未来的包管理工具 pipenv』

Kenneth Reitz 出品,必属精品。

# Python 打包历史

刚开始的时候,我们是这样安装包的。

curl http://pypi.python.org/packages/alsdasdl/requests.tar.gz | tar zxf
cd requests/
python setup.py install

这个问题初看起来不是问题,但是随着你安装程序的增多就知道有多么痛苦了。

  1. 有的依赖库依赖别的库你怎么解决?比如 pandas 需要安装 numpy
  2. 有的依赖库依赖 c 库怎么办?比如 LXML
  3. 在 python2.6.5 下,如果我需要安装两个不同版本的 Django 开发不同的软件怎么办?难道只能动态复制文件到 site-packages 里面?

后来,我们是这样安装包的。

easy_install requests

我们可以直接从 pypi 进行安装了。但尼玛,为什么 easy_install 安装很 easy, 但是没有 easy_uninstall?

好,2010 年后,我们继续前进:

  • 可以通过 pip 替代 easy_install 了。
  • 可以通过 virtualenv 管理项目的依赖库了。虽然说,还是不能像 ruby gem 一样同时把多个版本的的软件装在同一个系统里。
  • 可以通过 requirements 锁依赖了。

但,同期的其他编程语言社区分别出现了如下的包管理工具:

  • node -> yarn && npm , 有 lockfile
  • php -> composer , 有 lockfile
  • rust -> cargo , 有 lockfile
  • ruby -> bundler , 有 lockfile

而我大 Python 居然没跟上潮流

  • python -> pip && virtualenv/venv , 无 lockfile

PS: Python3.3 之后,默认可以直接使用 venv 模块,不需要再安装 virtualenv 了。但还是需要手动,并且用起来比较反直觉。

关于 requirements.txt

  • 如果你使用 pip freeze 来形成这个文件,则不直观,完全看不出来哪个依赖库依赖哪个依赖。
  • 如果你直接手动指定你所需要的库,比如 flask 的话,似乎又有些太直观了。

如果能有一个东西,既可以表示 freeze 的结果 (what you want),又可以表示你需要的库 (what you need). 就好了。

这当然可以考虑用两份 requirements 来解决。先安装 what you need 用来开发,然后 freeze 为 what you want 去部署。

当然,铺垫了这么多 K 神肯定是来介绍他的 pipenv 的。

比如说,我想查看,本项目的依赖库,直接 pipenv graph

coverage==4.5.1
fabric==2.0.1
  - cryptography [required: >=1.1, installed: 2.2.2]
    - asn1crypto [required: >=0.21.0, installed: 0.24.0]
    - cffi [required: >=1.7, installed: 1.11.5]
      - pycparser [required: Any, installed: 2.18]
    - idna [required: >=2.1, installed: 2.6]
    - six [required: >=1.4.1, installed: 1.11.0]
  - invoke [required: <2.0,>=1.0, installed: 1.0.0]
  - paramiko [required: >=2.4, installed: 2.4.1]
    - bcrypt [required: >=3.1.3, installed: 3.1.4]
      - cffi [required: >=1.1, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - six [required: >=1.4.1, installed: 1.11.0]
    - cryptography [required: >=1.5, installed: 2.2.2]
      - asn1crypto [required: >=0.21.0, installed: 0.24.0]
      - cffi [required: >=1.7, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - idna [required: >=2.1, installed: 2.6]
      - six [required: >=1.4.1, installed: 1.11.0]
    - pyasn1 [required: >=0.1.7, installed: 0.4.2]
    - pynacl [required: >=1.0.1, installed: 1.2.1]
      - cffi [required: >=1.4.1, installed: 1.11.5]
        - pycparser [required: Any, installed: 2.18]
      - six [required: Any, installed: 1.11.0]
flake8==3.5.0
  - mccabe [required: >=0.6.0,<0.7.0, installed: 0.6.1]
  - pycodestyle [required: <2.4.0,>=2.0.0, installed: 2.3.1]
  - pyflakes [required: >=1.5.0,<1.7.0, installed: 1.6.0]
# 其他省略

如何尝鲜?我最近更新到了之前写的一个库(代码写的惨不忍赌,最近准备重构,勿喷)

git clone git@github.com:twocucao/YaPyLib.git
cd YaPyLib/
brew install pipenv
pipenv --three
pipenv install --dev
pipenv shell

记住几个命令

pipenv --venv # 查看 venv 位置
pipenv --python 3.6.5
exit 退出 pipenv shell

至于其他的功能,参考官网自己摸索吧。

# FAQ 环节

FAQ 环节有一个问题非常有趣,应该把 lockfile 放在 git 仓库里面吗?

k 神是这么回答的 yes。 这个问题很久之前就在 issue 上回答过了

https://github.com/pypa/pipenv/issues/598

我刚开始觉得不提交会好一些,后来觉得 track 一下也无妨。

# 写在最后

在用 npm 和 yarn 的时候,我有这么一个想法,希望 python 圈子里面能出一个类似于包管理工具。今年 2 月份的时候把自己的项目迁移过来,发现 pipenv 用起来很挺舒服的。

pipenv 是未来。火速用上吧。

觉得有趣就点个赞或者关注下呗。