Pipenv的基本使用

https://farm4.staticflickr.com/3931/33173826122_b7ee8f1a26_k_d.jpg

这篇文档覆盖了Pipenv的一些基本特性。

☤ Pipfile与Pipfile.lock示例

Pipfiles contain information for the dependencies of the project, and supersedes the requirements.txt file used in most Python projects. You should add a Pipfile in the Git repository letting users who clone the repository know the only thing required would be installing Pipenv in the machine and typing pipenv install. Pipenv is a reference implementation for using Pipfile.

下面是一个简单的 Pipfile 示例以及对应的 Pipfile.lock

Pipfile示例

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"

[packages]
requests = "*"


[dev-packages]
pytest = "*"

Pipfile.lock示例

{
    "_meta": {
        "hash": {
            "sha256": "8d14434df45e0ef884d6c3f6e8048ba72335637a8631cc44792f52fd20b6f97a"
        },
        "host-environment-markers": {
            "implementation_name": "cpython",
            "implementation_version": "3.6.1",
            "os_name": "posix",
            "platform_machine": "x86_64",
            "platform_python_implementation": "CPython",
            "platform_release": "16.7.0",
            "platform_system": "Darwin",
            "platform_version": "Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64",
            "python_full_version": "3.6.1",
            "python_version": "3.6",
            "sys_platform": "darwin"
        },
        "pipfile-spec": 5,
        "requires": {},
        "sources": [
            {
                "name": "pypi",
                "url": "https://pypi.python.org/simple",
                "verify_ssl": true
            }
        ]
    },
    "default": {
        "certifi": {
            "hashes": [
                "sha256:54a07c09c586b0e4c619f02a5e94e36619da8e2b053e20f594348c0611803704",
                "sha256:40523d2efb60523e113b44602298f0960e900388cf3bb6043f645cf57ea9e3f5"
            ],
            "version": "==2017.7.27.1"
        },
        "chardet": {
            "hashes": [
                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691",
                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
            ],
            "version": "==3.0.4"
        },
        "idna": {
            "hashes": [
                "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
                "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f"
            ],
            "version": "==2.6"
        },
        "requests": {
            "hashes": [
                "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
                "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
            ],
            "version": "==2.18.4"
        },
        "urllib3": {
            "hashes": [
                "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
                "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
            ],
            "version": "==1.22"
        }
    },
    "develop": {
        "py": {
            "hashes": [
                "sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a",
                "sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3"
            ],
            "version": "==1.4.34"
        },
        "pytest": {
            "hashes": [
                "sha256:b84f554f8ddc23add65c411bf112b2d88e2489fd45f753b1cae5936358bdf314",
                "sha256:f46e49e0340a532764991c498244a60e3a37d7424a532b3ff1a6a7653f1a403a"
            ],
            "version": "==3.2.2"
        }
    }
}

☤ 一般推荐与版本控制

  • 通常情况下,把 PipfilePipfile.lock 都纳入版本控制。
  • 当需要兼容多个Python版本时,请勿把 Pipfile.lock 纳入版本控制。
  • Specify your target Python version in your Pipfile’s [requires] section. Ideally, you should only have one target Python version, as this is a deployment tool. python_version should be in the format X.Y (or X) and python_full_version should be in X.Y.Z format.
  • pipenv install 语法与 pip install 完全兼容,完整文档可见 这里
  • Note that the Pipfile uses the TOML Spec.

☤ Pipenv工作流示例

克隆、创建一个项目仓库:

$ cd myproject

如果已经有一个Pipfile,从Pipfile安装:

$ pipenv install

或者,添加一个包到你的项目中:

$ pipenv install <package>

如果 Pipfile 不存在会创建一个。否则,它的内容会自动更新加入新的包。

接下来,激活Pipenv的终端:

$ pipenv shell
$ python --version

这会启动一个新的终端进程,可以通过 exit 来退出。

☤ Pipenv升级工作流示例

  • 查看上游更新的内容: $ pipenv update --outdated
  • 升级包版本,有两种方法:
    1. 想要升级所有依赖包?只需要 $ pipenv update
    2. 想要一个个升级包?对每一个包 $ pipenv update <pkg>

☤ 从requirements.txt中导入

如果你运行 pipenv install 时只有一个 requirements.txt,pipenv会自动将文件内容导入进来为你创建一个 Pipfile

你也可以指定 $ pipenv install -r path/to/requirements.txt 导入某个requirements文件。

如果你的requirements文件中锚定了版本号,你可能需要编辑新的 Pipfile 去掉它们,让 pipenv 去管理版本。如果你需要保持 Pipfile.lock 中锚定的版本不变,运行 pipenv lock --keep-outdated 。别忘了立刻 更新

☤ 指定包的版本

你可以使用 语义版本规范 指定包的版本(如: major.minor.micro)。

例如,安装requests你可以用::

$ pipenv install requests~=1.2

Pipenv会安装 1.2 版本以及后续所有的次版本更新,但不包括 2.0

这会自动更新你的 Pipfile 一反映最新变化。

一般来说,Pipenv和pip使用相同的版本标识。但注意到 PEP 440 ,你不能使用包含连字符与加号的版本。

要用包含与不包含的版本比较你可以用::

$ pipenv install "requests>=1.4"   # will install a version equal or larger than 1.4.0
$ pipenv install "requests<=2.13"  # will install a version equal or lower than 2.13.0
$ pipenv install "requests>2.19"   # will install 2.19.1 but not 2.19.0

注解

高度推荐用双引号包裹包版本标识(如 "requests>2.19"),这是为了避免在基于Unix的操作系统中出现 输入输出重定向问题

~=== 标识符更加推荐,因为后者会使得pipenv无法更新包::

$ pipenv install "requests~=2.2"  # locks the major version of the package (this is equivalent to using ==2.*)

要防止安装包的某个版本可以使用 != 标识符。

想要获得关于有效标识符和更加复杂的使用方法请参考 the relevant section of PEP-440

☤ 指定Python的版本

想要使用一个已有的Python版本创建虚拟环境,使用 --python VERSON 选项,类似这样:

使用Python 3:

$ pipenv --python 3

使用Python 3.6:

$ pipenv --python 3.6

使用Python 2.7.14:

$ pipenv --python 2.7.14

如果提供了Python版本,就像这样,Pipenv会自动扫描系统上和提供的版本匹配的Python。

如果 Pipfile 还未创建会自动创建一个,看起来的效果是这样:

[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true

[dev-packages]

[packages]

[requires]
python_version = "3.6"

注解

[requires] python_version = "3.6" 的加入说明你的应用需要这个版本的Python,以后在运行 pipenv install 时会自动使用这个 Pipfile (比如在另一台机器上)。如果不能满足,可以自己删除这一节。

如果你没有在命令行中指定Python的版本,那么会自动选择 [requires] 中的``python_full_version`` 或 python_version 。执行时候回退到当前系统的默认Python版本。

可修改依赖 (如 -e . )

你可以让Pipenv以可修改模式安装某个路径——通常用于开发Python包时,安装当前工作目录。

$ pipenv install --dev -e .

$ cat Pipfile
...
[dev-packages]
"e1839a8" = {path = ".", editable = true}
...

注解

所有次级依赖也会加到 Pipfile.lock 中。如果没有加 -e 选项次级依赖将 会加到 Pipfile.lock 中。

☤ 用Pipenv管理环境

用来管理你的pipenv环境的三个主要命令是 $ pipenv install$ pipenv uninstall , 以及 $ pipenv lock

$ pipenv install

$ pipenv install 用于把包安装到pipenv虚拟环境及更新Pipfile。

与下面的形式的基本的安装命令一起:

$ pipenv install [package names]

用户可以提供这些额外的参数:

  • --two —— 在使用Python 2的虚拟环境中进行安装。
  • --three —— 在使用Python 3的虚拟环境中进行安装。
  • --python —— 在使用给定Python解释器的虚拟环境中进行安装。

警告

上述的选项均不能同时使用。同时它们也是 破坏性的,会删除你当前的虚拟环境,然后替换成一个适当版本的环境。

注解

Pipenv创建的虚拟环境可能与你预期的有所不同。危险字符(比如 $`!*@" 和空格、换行、制表符)会被替换成下划线。此外,当前目录的全路径会被编码成哈希值并追加到虚拟环境名称中来确保名称唯一。

  • --dev —— 同时安装 Pipfiledevelopdefault 里面的包。
  • --system ——使用系统的 pip 命令而不是虚拟环境中的。
  • --deploy — Make sure the packages are properly locked in Pipfile.lock, and abort if the lock file is out-of-date.
  • --ignore-pipfile ——忽略 Pipfile 直接从 Pipfile.lock 中安装。
  • --skip-lock ——忽略 Pipfile.lock,直接从 Pipfile 中安装。此外也不会更新 Pipfile.lock 以跟踪 Pipfile 的变化。

$ pipenv uninstall

$ pipenv uninstall 支持 pipenv install 中的全部参数,以及两个额外的选项, --all--all-dev

  • --all ——此参数会删除虚拟环境所有的包,但不改变Pipfile。
  • --all-dev ——此参数会删除虚拟环境中所有的开发包,并从Pipfile中删除。

$ pipenv lock

$ pipenv lock 用来创建一个 Pipfile.lock ,其中指明了项目的 所有 依赖(及次级依赖),它们的最新可以版本,与当前下载文件的哈希值。这确保了构建是可重复的,最重要是 确定性 的。

☤ 关于终端配置

作为子终端使用时,终端通常是未配置的,因此 $ pipenv shell --fancy 可能会出现不可预料的结果。如果是这样,尝试使用 $ pipenv shell ,它会使用「兼容模式」尝试启动一个未配置的子终端。

一个正确的终端配置仅在登录会话是设置类似 PATH 的环境变量,而不是在每次子终端启动时(因为通常配置成这样做)。在fish中,这类似于下面这样:

if status --is-login
    set -gx PATH /usr/local/bin $PATH
end

你应该在你的终端里也这样做,放在你的 ~/.profile or ~/.bashrc 或者其他合适的地方。

注解

终端以交互模式启动。这表示如果你的终端从某个文件读取交互模式的配置(如bash默认为交互模式寻找 ~/.bashrc 配置文件),你需要修改(或创建)这个文件。

如果你在用 $ pipenv shell 时遇到问题,检查一下 PIPENV_SHELL 环境变量,它若存在则会被 $ pipenv shell 使用。具体可参考 ☤ Configuration With Environment Variables

☤ 关于版本控制系统依赖的注意事项

你可以用pipenv从git或其他版本控制系统安装依赖,使用的URL应遵循以下规则:

<vcs_type>+<scheme>://<location>/<user_or_organization>/<repository>@<branch_or_tag>#egg=<package_name>

仅有 @<branch_or_tag> 部分是可选的。当通过SSH连接git时,你可以用简短URL前缀 git+git@<location>:<user_or_organization>/<repository>@<branch_or_tag>#<package_name> ,在解析时会被转译为 git+ssh://git@<location>

注意, 强烈推荐 你用可修改模式安装任何版本控制系统依赖,即 pipenv install -e ,以确保每次解析依赖时在仓库的最新版本的基础上进行,并且正确包含所有已知依赖。

下面的例子演示了如何从git仓库 https://github.com/requests/requests.gitv2.20.1 标签,以 requests 作包名安装:

$ pipenv install -e git+https://github.com/requests/requests.git@v2.20.1#egg=requests
Creating a Pipfile for this project...
Installing -e git+https://github.com/requests/requests.git@v2.20.1#egg=requests...
[...snipped...]
Adding -e git+https://github.com/requests/requests.git@v2.20.1#egg=requests to Pipfile's [packages]...
[...]

$ cat Pipfile
[packages]
requests = {git = "https://github.com/requests/requests.git", editable = true, ref = "v2.20.1"}

<vcs_type> 的有效值包括 gitbzrsvnhg<scheme> 的有效值包括 httphttpssshfile 。在特定情况下你也可以使用其他的前缀: svn 可以和 svn 组合使用, bzr 可以和 sftplp 组合使用。

可以到 这里 阅读更多pip对于版本控制系统支持的实现。更多关于其他版本控制系统依赖可选的选项,请参阅 Pipfile标准

☤ Pipfile.lock安全特性

Pipfile.lock 利用了 pip 中的一些很好的安全改进。默认情况下, Pipfile.lock 会生成所有已下载包的sha256哈希值。这使得 pip 在不安全网络情况下,保证你安装了你想要的包,或者从一个不信任的PyPI源下载依赖。

我们高度推荐将一个开放环境中的项目提升到生产环境来部署。你可以用 pipenv lock 来固化开发环境中的依赖,然后将生成的 Pipfile.lock 部署到所有生产环境,来达到可复制构建的效果。

注解

If you’d like a requirements.txt output of the lockfile, run $ pipenv lock -r. This will include all hashes, however (which is great!). To get a requirements.txt without hashes, use $ pipenv run pip freeze.