A Brief Introduction to Pipenv

它同时解决了以下三个问题

版本控制

当你执行 pip install flask 的时候,默认安装的是 flask 的最新版,如果你因为兼容性的问题不能使用最新的版本,那样会出现问题。现在比较常见的 workaround 是使用 pip freeze > requirements.txt 来把包及其对应的版本 dump 到 TXT 文件。

环境隔离

项目在不同时期开始的时候所用的包版本可能会有所不同,譬如老项目用的还是 django 1.x,而新项目已经在尝试 2.0 的版本了。这时候如果项目所依赖的包版本有出入,就会出现问题。比较通用的做法是用 virutalenv(在 Python 3 里叫作 venv)来让项目有自己专属的环境配置,从而避免不必要的错误。

不同包对另一依赖的版本要求

有时候不同第三方包会依赖同一个包,但是它们的版本需求却有所出入。譬如现有 package_apackage_b,前者需要的 package_c 版本是 ≥1.0,而后者需要的则是 ≤ 2.0。这时候你希望 pip 会给你安装一个 ≥ 1.0 且 ≤ 2.0 的 package_c

然而,现阶段的 pip 无法给你自动解决这个问题。手动解决的方法是,在 requirements.txt 文件中,写入 package_c>=1.0,<=2.0 ,并且这一行需要在 package_apackage_b 之前。

package_c>=1.0,<=2.0
package_a
package_b

但是这里面出现了一个情况:你现在需要特意关心你所用的包需要的依赖了。之前的你是不需要关心这个的。

好的包管理工具应该可以自动给你解决这些,Pipenv 都做到了。

使用

两个核心:Pipfile & Pipfile.lock

使用 Pipenv 之后,你的项目根目录会有 PipfilePipfile.lock 这两个问题,如果你之前接触过 Ruby,可能你会马上联想到 RubyGems

Pipfile

大致上可以理解为用作取代 pip 的 requirements.txt值得一提的是,将来 pip 很有可能能够处理 Pipfile。此外,Pipenv 现在是 Python 官方推荐的包管理工具

Pipfile 不需要包含子依赖,譬如 requests 依赖 chardetPipfile 只需要包含 requests 就好了,Pipenv 会自动安装 chardet

Pipfile.lock

通过记录包具体的版本号和哈希值,确保重建的环境与先前的一致。现在的 pip 同样支持这个功能。可以参考以下例子,需要注意的是部分信息用 ... 在此例子里面省略了。

{
    "_meta": {
        ...
    },
    "default": {
        "flask": {
            "hashes": [
                "sha256:6c3130c8927109a08225993e4e503de4ac4f2678678ae211b33b519c622a7242",
                "sha256:9dce4b6bfbb5b062181d3f7da8f727ff70c1156cbb4024351eafd426deb5fb88"
            ],
            "version": "==0.12.1"
        },
        "requests": {
            "editable": true,
            "git": "https://github.com/requests/requests.git",
            "ref": "4ea09e49f7d518d365e7c6f7ff6ed9ca70d6ec2e"
        },
        "werkzeug": {
            "hashes": [
                "sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b",
                "sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c"
            ],
            "version": "==0.14.1"
        }
        ...
    },
    "develop": {
        "pytest": {
            "hashes": [
                "sha256:8970e25181e15ab14ae895599a0a0e0ade7d1f1c4c8ca1072ce16f25526a184d",
                "sha256:9ddcb879c8cc859d2540204b5399011f842e5e8823674bf429f70ada281b3cc6"
            ],
            "version": "==3.4.1"
        },
        ...
    }
}

从上面例子可以看到,所有的包,包括都其所需的依赖包(即使没有在 Pipfile 出现),都有具体的版本号。

这个文件无需手动编辑,如果想要更新它的话,应该用命令 pipenv lock 重新生成。

我之前一直在用 requirements.txt, 我要怎么把它转换为 Pipfile?

直接 pipenv install 就好了!Pipenv 会自动检测 requirements.txt 是否存在并把它转为 Pipfile 的格式:

requirements.txt found, instead of Pipfile! Converting…
Warning: Your Pipfile now contains pinned versions, if your requirements.txt did.
We recommend updating your Pipfile to specify the "*" version, instead.

Comments