2025-08-28
Python基础
00
请注意,本文编写于 114 天前,最后修改于 113 天前,其中某些信息可能已经过时。

目录

前言
1. 为什么要使用 Pipenv?
2. pipenv的简单使用
1. 安装pipenv
2. pipenv虚拟环境创建与指定py版本
3. pipenv依赖管理
1. 安装软件包
2. 查看已安装的包与卸载依赖
3. 锁定依赖关系
1. 为什么你没运行 pipenv lock,却已经有 Pipfile.lock?
2. 那么显式运行pipenv lock 命令的必要性与时机在哪里?
3. 那么运行pipenv lock前后有什么影响?
3. macOS + Windows 验证 Pipfile.lock 的核心作用 —— 跨平台重现相同依赖环境。
1. 在 macOS 上准备环境
2. 拷贝文件到 Windows
3. 在 Windows 上复现环境(确保windows系统上也存在pyenv安装的python 3.9.1.)
1. 只安装 生产依赖(忽略 dev)
2. 安装全部依赖(开发环境依赖)
3. 只安装dev依赖

前言

 本片文章只是根据pipenv官方文档的简单实践的个人记录,若想对pipenv有详细的理解,请移步Pipenv:面向人类的 Python 开发工作流程

1. 为什么要使用 Pipenv?

以下内容为官网内容的个人理解

  1. 简化的依赖管理:无需单独使用 pip 和 virtualenv:
  • Pipenv 结合了 pip 和 virtualenv 两个工具的功能,简化了依赖管理的过程。

  • pip:用于安装 Python 包

  • virtualenv:用于创建独立的虚拟环境,以确保不同项目之间不会互相干扰

  • Pipenv 让你不再需要单独手动执行这两个工具,而是通过一个命令同时管理虚拟环境和包依赖。例如:

  • pipenv install 会同时创建虚拟环境,并安装在 Pipfile 中列出的依赖。

  • pipenv shell 会自动激活该虚拟环境,省去了手动使用 virtualenv 的步骤

  1. 确定性构建:Pipfile.lock 确保可以在不同的系统上重现完全相同的环境
  • Pipfile 和 Pipfile.lock 是 Pipenv 使用的两个核心文件:

  • Pipfile:列出了项目的直接依赖(类似于传统的 requirements.txt)

  • Pipfile.lock:记录了所有安装的依赖项及其精确版本(包括所有的子依赖),确保在不同系统间通过pipenv install安装的依赖项版本完全一致。

  1. 安全第一:包哈希记录在锁定文件中,并在安装期间进行验证,以防止供应链攻击
  • Pipenv 在安装依赖时,会将包的哈希值记录在 Pipfile.lock 文件中。哈希值是包的唯一标识符,确保包在下载和安装过程中没有被篡改。

  • 在安装依赖时,Pipenv 会 验证每个包的哈希值 是否与 Pipfile.lock 中记录的匹配。若不匹配,就表示包可能被篡改,从而避免了 供应链攻击。

  1. 依赖可见性:轻松可视化您的依赖关系图(pipenv graph)
  • Pipenv 提供了 pipenv graph 命令,它可以生成并显示 项目的依赖关系图,包括直接和间接依赖。这对理解项目的依赖结构非常有帮助,尤其是当项目有很多依赖时。
zsh
pipenv graph
zsh
requests==2.25.1 - certifi [required: >=2017.4.17, installed: 2020.12.5] - chardet [required: <5, installed: 4.0.0]
  1. 环境隔离:每个项目都有自己独立的虚拟环境,防止依赖冲突
  • Pipenv 会为每个项目创建一个 隔离的虚拟环境。这样,你在不同项目中安装的依赖不会互相干扰,避免了 版本冲突。

  • 通过 pipenv install,Pipenv 会为每个项目创建一个独立的虚拟环境,确保项目依赖是独立的。

  • 每个项目的虚拟环境包含 Pipfile 和 Pipfile.lock 中列出的依赖项,而不会与系统中其他 Python 项目的依赖混合。

  1. 开发工作流程集成:支持使用 .env 文件和开发与生产依赖关系进行本地定制
  • Pipenv 允许你使用 .env 文件来设置开发环境中所需的 环境变量,这样你可以轻松管理不同环境(如开发环境和生产环境)中的配置。

  • .env 文件:用于定义环境变量,例如 API 密钥、数据库连接字符串等。这些环境变量会自动加载到项目中,便于本地开发配置。

  • 此外,Pipenv 还支持在同一项目中管理 开发依赖 和 生产依赖

  • 开发依赖是指仅在开发过程中使用的工具,如 pytest 等测试工具。

  • 生产依赖是指项目运行时必须的依赖,如 Flask 或 Django。

  • 使用以下命令区分安装

  • 安装开发依赖:pipenv install --dev

  • 安装生产依赖:pipenv install

  1. 最新依赖版本:鼓励使用最新的依赖项以最大限度地减少安全漏洞
  • Pipenv 鼓励使用 最新版本的依赖包,以确保你的项目尽可能地使用 最新的安全修复和功能。

  • 每次运行 pipenv install,都会尽量安装包的 最新稳定版本,并且会自动为你 锁定 该版本(在 Pipfile.lock 中记录)。

2. pipenv的简单使用

1. 安装pipenv

bash
# pipx安装 pipx install pipenv # 安装后验证 pipenv --version # 升级pipenv pipx upgrade pipenv

2. pipenv虚拟环境创建与指定py版本

bash
# 创建项目目录 mkdir Penv_Project cd Penv_Project # 使用系统中的python解释器创建虚拟环境 pipenv --python /Users/${username}/.pyenv/versions/3.9.1/bin/python3.9 # 如果安装了pyenv,Pipenv 可以自动使用它来查找并安装所需的 Python 版本: pipenv --python 3.9.1 # 纯净的Pipfile文件内容如下 [[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] [dev-packages] [requires] python_version = "3.9" python_full_version = "3.9.1" # 查找虚拟环境目录,方便Pycharm配置解释器 pipenv --venv # 例:/Users/.local/share/virtualenvs/Penv_Project-xMAvr6tj,其中{Penv_Project}为项目名称、{xMAvr6tj}为虚拟环境名称。 # 环境激活 pipenv shell # 退出 exit # 删除 Pipfile 和 Pipfile.lock(把依赖声明文件清空) rm Pipfile Pipfile.lock # linux del -p Pipfile Pipfile.lock # win # 删除虚拟环境 pipenv --rm

提示

  1. 如果当前目录(或上级目录)有 requirements.txt,pipenv install / pipenv --python xxx 会尝试导入它里面的依赖,自动写入 [packages],所以为了生成一个干净的Pipfile,应确保项目目录与上级目录不存在requirements.txt文件,或者使用PIPENV_IGNORE_REQUIREMENTS=1 pipenv --python 3.9.1命令创建虚拟环境,来避免导入同级目录的 requirements.txt。
  2. 推荐使用pyenv+pipenv进行版本与依赖管理。

3. pipenv依赖管理

1. 安装软件包

bash
# 普通安装 $ pipenv install requests # 指定依赖版本安装 $ pipenv install "django>=4.0.0" # 安装开发依赖项 $ pipenv install pytest --dev # 升级更新依赖项 pipenv update --outdated # 查看所有需要更新的依赖项 pipenv update # 更新所有包的依赖项 pipenv update <包名> # 更新指定的包的依赖项 # 安装后查看Pipfile中的内容如下 [[source]] url = "https://pypi.org/simple" verify_ssl = true name = "pypi" [packages] requests = "*" django = ">=4.0.0" [dev-packages] pytest = "*" [requires] python_version = "3.9" python_full_version = "3.9.1"

提示

  1. 若使用pipenv install安装不存在的依赖,如:pipenv install request,则会报错:ERROR: Failed to lock Pipfile.lock!,是 lock 文件坏了,而是因为 pipenv 无法解析依赖(你要安装的 request 包不存在),所以锁定失败。

2. 查看已安装的包与卸载依赖

bash
# 查看依赖关系图 pipenv graph # 运行结果如下 Django==4.2.23 ├── asgiref │ └── typing_extensions └── sqlparse pytest==8.4.1 ├── exceptiongroup │ └── typing_extensions ├── iniconfig ├── packaging ├── pluggy ├── Pygments └── tomli requests==2.32.5 ├── certifi ├── charset-normalizer ├── idna └── urllib3 # 查看已安装的包 pipenv run pip list # 卸载软件包 pipenv uninstall XXX # 卸载XXX模块并从Pipfile中移除 pipenv uninstall --all # 卸载全部包并从Pipfile中移除 pipenv uninstall --all-dev # 卸载全部开发包并从Pipfile中移除

3. 锁定依赖关系

 我们在第一次使用pipenv install进行依赖安装成功后,我们会发现在当前目录下会自动生成一个Pipfile.lock文件,那他是怎么出现的呢,简单分析一下:

1. 为什么你没运行 pipenv lock,却已经有 Pipfile.lock?

这是 pipenv 的自动行为:

  • 当你第一次运行 pipenv install xxx 时,pipenv 会:

    1. 安装指定的依赖到虚拟环境里
    2. 写入/更新 Pipfile
    3. 自动调用 pipenv lock 的逻辑,生成或更新 Pipfile.lock

所以你没手动执行 pipenv lock,但它在 install 时就自动触发了 lock,这就是你看到有 Pipfile.lock 文件的原因。

2. 那么显式运行pipenv lock 命令的必要性与时机在哪里?

  • 修改了 Pipfile(手动改依赖/版本)。
  • 出现 依赖解析错误,需要重新计算依赖树。
  • 切换 Python 版本,想确保兼容性。
    1. 你要确保锁定的依赖树能在指定Python版本下运行。
    2. 比如你本地是 3.11,但项目部署环境是 3.9,就需要用这个参数来模拟。
    3. 跨版本开发/部署时非常重要(比如本地 macOS 是 3.12,但生产服务器只有 3.9)。
    4. 如果开发/生产环境版本一致,就不需要。
  • CI/CD 中自动生成环境时,保证一致性

3. 那么运行pipenv lock前后有什么影响?

  • 如果依赖没变:

    1. pipenv lock 前后的 Pipfile.lock 文件几乎一样,内容不会有实质性差别。
  • 如果 Pipfile 变了 / PyPI 有新版本可用:

    1. 运行 pipenv lock 会根据 Pipfile 重新解析,可能:
    2. 升级/降级某些依赖的子依赖
    3. 更新哈希值
    4. 重新写入 Pipfile.lock
  • 如果手动改过 Pipfile.lock:

    1. 下次运行 pipenv lock 会覆盖你手动的修改。

3. macOS + Windows 验证 Pipfile.lock 的核心作用 —— 跨平台重现相同依赖环境。

1. 在 macOS 上准备环境

bash
# 指定依赖版本安装 $ pipenv install "django>=4.0.0" # 安装开发依赖项 $ pipenv install pytest --dev $ pipenv install "selenium==4" --dev # 锁文件 pipenv lock

此时目录下有:

  • Pipfile
  • Pipfile.lock

2. 拷贝文件到 Windows

把这两个文件复制到 Windows 主机,目标目录结构类似:

bash
C:\Users\<你用户名>\Projects\Penv_Project │── Pipfile │── Pipfile.lock

3. 在 Windows 上复现环境(确保windows系统上也存在pyenv安装的python 3.9.1.)

1. 只安装 生产依赖(忽略 dev)

shell
# 进入项目目录 cd C:\Users\<你用户名>\Projects\Penv_Project # 运行 pipenv sync 默认只安装生产依赖(即 [packages] 里的)。 pipenv sync

验证安装结果

shell
D:\Env\penv_Project>pipenv run pip list Package Version ----------------- ------- asgiref 3.9.1 Django 4.2.23 pip 25.2 setuptools 80.9.0 sqlparse 0.5.3 typing_extensions 4.15.0 D:\Env\penv_Project>pipenv shell Launching subshell in virtual environment... Microsoft Windows [Version 10.0.19045.5965] (c) Microsoft Corporation。保留所有权利。 (Penv_Project-6ZrF6Oux) D:\Env\penv_Project>python --version Python 3.9.1 (Penv_Project-6ZrF6Oux) D:\Env\penv_Project>pipenv graph Django==4.2.23 ├── asgiref │ └── typing_extensions ├── sqlparse └── tzdata

2. 安装全部依赖(开发环境依赖)

shell
# 进入项目目录 cd C:\Users\<你用户名>\Projects\Penv_Project # 安装全部依赖 pipenv sync --dev

验证安装结果

shell
(penv_Project-cUw9fR6_) D:\Env\penv_Project>python --version Python 3.9.1 (penv_Project-cUw9fR6_) D:\Env\penv_Project>pipenv graph certifi==2025.8.3 Django==4.2.23 ├── asgiref │ └── typing_extensions ├── sqlparse └── tzdata pyOpenSSL==25.1.0 ├── cryptography │ └── cffi │ └── pycparser └── typing_extensions pytest==8.4.1 ├── colorama ├── exceptiongroup │ └── typing_extensions ├── iniconfig ├── packaging ├── pluggy ├── Pygments └── tomli selenium==4.0.0 ├── trio │ ├── attrs │ ├── cffi │ │ └── pycparser │ ├── exceptiongroup │ │ └── typing_extensions │ ├── idna │ ├── outcome │ │ └── attrs │ ├── sniffio │ └── sortedcontainers ├── trio-websocket │ ├── exceptiongroup │ │ └── typing_extensions │ ├── outcome │ │ └── attrs │ ├── trio │ │ ├── attrs │ │ ├── cffi │ │ │ └── pycparser │ │ ├── exceptiongroup │ │ │ └── typing_extensions │ │ ├── idna │ │ ├── outcome │ │ │ └── attrs │ │ ├── sniffio │ │ └── sortedcontainers │ └── wsproto │ └── h11 └── urllib3 urllib3-secure-extra==0.1.0

3. 只安装dev依赖

 这种场景不合理因为 dev 依赖的存在前提,是在 开发一个能运行的项目。 如果项目的核心依赖(比如 Django、Flask、pandas)都没装,单独装 pytest、selenium 是没有意义的: 你连代码都跑不起来,测试也无法运行。 所以 pipenv 逻辑上不支持“只要 dev”的场景。

本文作者:精卫

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!