由 Kenneth Reitz 创建的“人类的 Python 开发工作流程” Pipenv 在一年多前问世,现已成为 Python 官方推荐的资源,用于管理包依赖。但人们对于它解决了哪些问题,以及它比使用 pip
和 requirements.txt
文件的标准工作流程更有用之处仍然感到困惑。在本月的 Python 专栏中,我们将填补这些空白。
Python 包安装的简要历史
为了理解 Pipenv 解决的问题,了解 Python 包管理的发展历程很有帮助。
让我们回到最初的 Python 版本。我们有了 Python,但没有干净利落地安装包的方法。
然后出现了 Easy Install,这是一个可以相对轻松地安装其他 Python 包的包。但它有一个缺点:卸载不再需要的包并不容易。
接着出现了 pip,大多数 Python 用户都很熟悉它。pip
允许我们安装和卸载包。我们可以指定版本,运行 pip freeze > requirements.txt
将已安装包的列表输出到文本文件,并使用同一个文本文件通过 pip install -r requirements.txt
安装应用程序所需的一切内容。
但 pip
不包含将包彼此隔离的方法。我们可能在开发使用相同库的不同版本的应用程序,因此我们需要一种方法来实现这一点。随之而来的是 虚拟环境,它使我们能够为我们开发的每个应用程序创建小型、隔离的环境。我们已经看到了许多用于管理虚拟环境的工具:virtualenv、venv、virtualenvwrapper、pyenv、pyenv-virtualenv、pyenv-virtualenvwrapper,甚至更多。它们都与 pip
和 requirements.txt
文件配合良好。
新秀:Pipenv
Pipenv 旨在解决几个问题。
首先,需要 pip
库进行包安装,还需要一个库来创建虚拟环境,还需要一个库来管理虚拟环境,以及与这些库关联的所有命令,这本身就是一个问题。这有很多东西需要管理。Pipenv 附带包管理和虚拟环境支持,因此您可以使用一个工具来安装、卸载、跟踪和记录您的依赖项,以及创建、使用和组织您的虚拟环境。当您使用 Pipenv 启动一个项目时,如果您尚未使用虚拟环境,Pipenv 将自动为该项目创建一个虚拟环境。
Pipenv 通过放弃 requirements.txt
规范并将其替换为名为 Pipfile 的新文档来实现这种依赖管理。当您使用 Pipenv 安装库时,您项目的 Pipfile
会自动更新,其中包含该安装的详细信息,包括版本信息,以及可能的 Git 存储库位置、文件路径和其他信息。
其次,Pipenv 希望使管理复杂的相互依赖关系变得更容易。您的应用程序可能依赖于特定版本的库,而该库可能依赖于另一个库的特定版本,这种依赖关系会一直延续下去。当您的应用程序使用的两个库具有冲突的依赖关系时,您的生活可能会变得艰难。Pipenv 希望通过在名为 Pipfile.lock
的文件中跟踪应用程序的相互依赖关系树来缓解这种痛苦。Pipfile.lock
还验证在生产环境中使用的是正确版本的依赖项。
此外,当多个开发人员在一个项目上工作时,Pipenv 非常方便。使用 pip
工作流程,Casey 可能会安装一个库,并花费两天时间使用该库实现一个新功能。当 Casey 提交更改时,他们可能会忘记运行 pip freeze
来更新 requirements 文件。第二天,Jamie 拉取 Casey 的更改,突然测试失败了。需要花费时间才能意识到问题是 requirements 文件中缺少 Jamie 未在虚拟环境中安装的库。
由于 Pipenv 会在您安装依赖项时自动记录依赖项,因此如果 Jamie 和 Casey 使用的是 Pipenv,则 Pipfile
将会自动更新并包含在 Casey 的提交中。Jamie 和 Casey 将节省时间并更快地交付他们的产品。
最后,使用 Pipenv 向在您的项目上工作的其他人发出信号,表明它附带了一种标准化的方法来安装项目依赖项以及开发和测试需求。使用 pip
和 requirements 文件的工作流程意味着您可能有一个单独的 requirements.txt
文件,或者用于不同环境的多个 requirements 文件。例如,您的同事可能不清楚在他们的笔记本电脑上运行项目时,他们应该运行 dev.txt
还是 local.txt
。当两个类似的 requirements 文件彼此之间严重不同步时,也可能造成混淆:local.txt
是否已过时,或者它是否真的应该与 dev.txt
有那么大的不同?多个 requirements 文件需要更多的上下文和文档,才能使其他人能够正确且按预期安装依赖项。这种工作流程有可能使同事感到困惑并增加您的维护负担。
使用 Pipenv,它为您提供 Pipfile
,让您可以通过为您管理不同环境的依赖项来避免这些问题。此命令将安装主要项目依赖项
pipenv install
添加 --dev
标记将安装开发/测试需求
pipenv install --dev
使用 Pipenv 还有其他好处:它具有更好的安全功能,以更易于理解的格式绘制您的依赖关系图,无缝处理 .env
文件,并且可以自动处理开发环境与生产环境在一个文件中不同的依赖关系。您可以在 文档 中阅读更多内容。
Pipenv 实践
Pipenv 的基本用法在官方 Python 打包教程的 管理应用程序依赖项 部分中详细介绍。要安装 Pipenv,请使用 pip
pip install pipenv
要安装在您的项目中使用的包,请更改到您项目的目录。然后要安装一个包(我们将以 Django 为例),请运行
pipenv install django
您将看到一些输出,表明 Pipenv 正在为您的项目创建 Pipfile
。
如果您尚未使用虚拟环境,您还将看到 Pipenv 的一些输出,表明它正在为您创建一个虚拟环境。
然后,您将看到您在安装包时通常看到的输出。
要生成 Pipfile.lock
文件,请运行
pipenv lock
您还可以使用 Pipenv 运行 Python 脚本。要运行名为 hello.py
的顶级 Python 脚本,请运行
pipenv run python hello.py
您将在控制台中看到您期望的结果。
要启动 shell,请运行
pipenv shell
如果您想将当前使用 requirements.txt
文件的项目转换为使用 Pipenv,请安装 Pipenv 并运行
pipenv install requirements.txt
这将创建一个 Pipfile 并安装指定的 requirements。考虑一下您的项目已升级!
了解更多
查看 Pipenv 文档,特别是 Pipenv 的基本用法,以进一步了解。Pipenv 的创建者 Kenneth Reitz 在最近的 PyTennessee 活动上就 Pipenv 发表了题为“Python 依赖管理的未来”的演讲。该演讲没有录制,但他的 幻灯片 有助于理解 Pipenv 的作用及其解决的问题。
3 条评论