用 Pipenv 统一 Python 虚拟环境与依赖锁定

2026-09-27 47 预计阅读时间: 1 分钟
来源: realpython.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:7 分钟

传统 Python 项目经常同时使用 pip 安装包、virtualenv 创建环境,再手工维护 requirements.txt。这套组合可以工作,但开发者必须自己保证虚拟环境、直接依赖和最终安装版本彼此一致。Pipenv 将这些工作收拢到一个命令行工具中,并用 Pipfile 与 Pipfile.lock 分别描述依赖意图和可复现的安装结果。

Pipenv 实际解决了什么

Pipenv 的核心不是换一种方式执行 pip install,而是把依赖管理流程串联起来:

  • 自动为项目创建和选择虚拟环境;
  • 将正式依赖与开发依赖分开管理;
  • 使用 Pipfile 记录项目需要哪些包;
  • 使用 Pipfile.lock 锁定具体版本及哈希;
  • 通过统一命令在虚拟环境中运行程序、测试和工具。

两个文件承担不同职责。Pipfile 更像开发者维护的声明文件,例如允许 Flask 使用某个版本范围;Pipfile.lock 则记录依赖解析后的精确版本。团队通常应同时提交这两个文件,但不应手工修改锁文件。

一个简化的 Pipfile 大致如下:

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

[packages]
flask = "*"

[dev-packages]
pytest = "*"

[requires]
python_version = "3.12"

这里的 [packages] 用于运行时依赖,[dev-packages] 用于测试、格式化和静态检查等开发工具。具体版本会进一步写入 Pipfile.lock。

从空目录启动一个可运行项目

下面可以创建一个最小 Flask 服务。运行前需要安装 Python 3.12;如果使用其他版本,请相应修改 pipenv --python 参数。

先安装 Pipenv。使用 pipx 可以让 Pipenv 自身与业务项目隔离:

python -m pip install --user pipx
python -m pipx ensurepath
pipx install pipenv

重新打开终端后,创建项目并安装依赖:

mkdir pipenv-demo
cd pipenv-demo

pipenv --python 3.12
pipenv install flask
pipenv install --dev pytest

cat > app.py <<'PY'
from flask import Flask, jsonify

app = Flask(__name__)


@app.get('/health')
def health():
    return jsonify(status='ok')


if __name__ == '__main__':
    app.run(host='127.0.0.1', port=5000)
PY

pipenv run python app.py

在另一个终端中验证服务:

curl http://127.0.0.1:5000/health

预期响应为:

{"status":"ok"}

pipenv run 不要求当前终端先进入虚拟环境,适合脚本和 CI。需要连续执行多条交互式命令时,也可以进入环境:

pipenv shell
python app.py

退出时执行 exit。日常自动化中更推荐显式使用 pipenv run <command>,因为命令依赖哪个环境会更加清楚。

安装、升级与检查依赖

添加带版本范围的包时,可以把约束直接交给 Pipenv:

pipenv install 'requests~=2.32'
pipenv install --dev 'pytest>=8,<9'

这些命令会更新 Pipfile,重新解析依赖,并更新锁文件。查看完整依赖树可以使用:

pipenv graph

如果只修改了 Pipfile,可以显式重新生成锁文件:

pipenv lock

升级依赖前应先检查变更范围,并运行测试。可以这样实践:

pipenv update
pipenv run pytest

git diff -- Pipfile Pipfile.lock

不要只看 Pipfile 是否变化。一次看似简单的顶层依赖升级,可能同时改变多个间接依赖,因此 Pipfile.lock 的差异和测试结果同样重要。

删除依赖时也应通过 Pipenv 操作:

pipenv uninstall requests
pipenv uninstall --dev pytest

如果只是想删除项目对应的虚拟环境,而保留依赖文件,可以执行:

pipenv --rm

之后再次运行 pipenv install,Pipenv 会重建环境。

在 CI 和生产环境中坚持使用锁文件

开发机器可以解析新的依赖版本,部署环境则通常应该安装已经审核过的锁定结果。CI 可以采用下面的流程:

python -m pip install pipenv
pipenv install --dev --deploy --ignore-pipfile
pipenv run pytest

其中:

  • --dev 安装测试等开发依赖;
  • --deploy 在锁文件不符合要求时让命令失败,而不是静默继续;
  • --ignore-pipfile 要求按照锁文件安装,不重新根据 Pipfile 解析版本。

生产环境通常不需要开发依赖:

python -m pip install pipenv
pipenv install --deploy --ignore-pipfile
pipenv run python app.py

在已经由容器提供隔离能力、不希望容器内部再创建虚拟环境时,可以考虑安装到容器当前 Python 环境:

pipenv install --system --deploy --ignore-pipfile

--system 会改变安装位置,应只在容器或明确隔离的构建环境中使用,不建议直接对开发机的系统 Python 执行。

采用前的检查清单

Pipenv 适合希望用一个工具统一虚拟环境、依赖声明和锁文件的项目。引入时建议确认以下事项:

  • 团队成员和 CI 使用兼容的 Python 版本;
  • Pipfile 与 Pipfile.lock 都纳入版本控制;
  • 开发依赖放入 [dev-packages],避免进入生产环境;
  • CI 使用锁文件安装,并在锁文件过期时立即失败;
  • 升级依赖后检查锁文件差异并执行完整测试;
  • 不对本机系统 Python 随意使用 --system。

Pipenv 减少的是工具之间的接缝,而不是依赖管理本身的复杂度。对于已有稳定 requirements.txt 流程的项目,迁移收益需要结合团队习惯评估;对于新项目或经常出现环境不一致的问题,它能提供一条更集中、也更容易审查的工作流。


相关推荐