Skip to Content

venv

一、为什么需要虚拟环境?(The “Why”)

想象一下你在厨房做饭,但只有一个工具箱,里面放着你做所有菜系(中餐、法餐、墨西哥菜)需要的所有工具和香料。

  • 项目A (做中餐):你需要酱油、八角和一把中式菜刀。
  • 项目B (做墨西哥菜):你需要辣椒粉、孜然和玉米饼压制机。
  • 项目C (做法餐):你需要黄油、迷迭香和 requests 库的 2.20 版本(一个特定的工具)。
  • 项目D (最新的 AI 项目):你需要 requests 库的最新 2.28 版本,因为它修复了一个重要的 bug。

现在问题来了:你的工具箱里到底应该放哪个版本的 requests 库?如果为项目 D 升级了它,可能会导致项目 C 无法正常工作,因为项目 C 依赖于旧版本的特定功能。

这就是所谓的 “依赖地狱”(Dependency Hell)

Python 虚拟环境就是解决这个问题的完美方案。

它允许你为每个项目创建一个 独立的、隔离的“厨房”或“工具箱”

  • 项目 A 的虚拟环境里只放中餐的工具。
  • 项目 B 的虚拟环境里只放墨西哥菜的工具。
  • 项目 C 的虚拟环境里安装 requests==2.20
  • 项目 D 的虚拟环境里安装 requests==2.28

它们之间互不干扰,世界和平。


二、虚拟环境是什么?(The “What”)

从技术上讲,一个虚拟环境是一个 独立的目录,它包含了:

  1. 一个特定版本的 Python 解释器:通常是创建环境时所用的系统 Python 解释器的一个副本或符号链接。
  2. 一个独立的 site-packages 目录:这是最关键的部分。你通过 pip install 安装的所有第三方库(如 langchain, requests, numpy)都将被安装到这个独立的目录里,而不是系统的全局 site-packages 目录。
  3. 激活脚本:一些脚本文件(如 activate),用于修改你当前终端会话的配置,使其“指向”这个虚拟环境。

当你“激活”一个虚拟环境时,你的终端会话就会优先使用这个环境内的 Python 解释器和库,从而实现了隔离。


三、如何使用虚拟环境?(The “How” - 使用内置的 venv 模块)

从 Python 3.3 开始,venv 模块被内置到标准库中,这是官方推荐的创建虚拟环境的方式。

步骤 1:创建虚拟环境

  1. 打开你的终端(Terminal, PowerShell, CMD)。
  2. 进入你的项目文件夹。
    mkdir my-great-project cd my-great-project
  3. 运行 venv 模块来创建一个虚拟环境。通常,我们将其命名为 venv.venv
    # 语法: python -m venv <环境名称> python -m venv venv
    • python -m venv:告诉 Python 运行 venv 模块。
    • venv (第二个):是你给这个虚拟环境目录起的名字。

执行后,你的项目文件夹下会出现一个名为 venv 的新目录,里面包含了 Python 解释器和相关文件。

步骤 2:激活虚拟环境

创建环境后,你需要“激活”它才能使用。激活命令因操作系统而异。

  • 在 macOS / Linux 上:
    source venv/bin/activate
  • 在 Windows (CMD 或 PowerShell) 上:
    .\venv\Scripts\activate

如何判断是否激活成功? 激活后,你的终端提示符前面会出现 (venv) 的字样,像这样:

# macOS/Linux (venv) $ # Windows (venv) C:\path\to\my-great-project>

这个 (venv) 前缀是你最好的朋友,它时刻提醒你正处于一个隔离的环境中。

步骤 3:在虚拟环境中使用 Pip

激活环境后,你使用的 pip 就是这个环境专属的 pip

# 这会将 requests 安装到 ./venv/lib/pythonX.Y/site-packages/ 目录下 (venv) $ pip install requests # 检查已安装的包,你会发现只有少数几个基础包和刚刚安装的 requests (venv) $ pip list

步骤 4:停用虚拟环境

当你完成工作,想要回到系统的全局 Python 环境时,只需运行:

(venv) $ deactivate

运行后,提示符前面的 (venv) 就会消失。

步骤 5:删除虚拟环境

不再需要这个虚拟环境了?直接删除文件夹即可,非常干净。

# 在 macOS / Linux 上 rm -rf venv # 在 Windows 上 rmdir /s venv # 或者直接在文件浏览器中删除 venv 文件夹

四、最佳实践:使用 requirements.txt 管理依赖

虚拟环境解决了隔离问题,但如何让其他人(或者未来的你)知道这个项目需要哪些依赖呢?答案是 requirements.txt 文件。

  1. 生成 requirements.txt 文件激活的虚拟环境中,运行以下命令:

    (venv) $ pip freeze > requirements.txt
    • pip freeze:会列出当前环境中所有已安装的第三方包及其精确版本号。
    • >:是一个重定向符号,将 pip freeze 的输出写入到 requirements.txt 文件中。

    现在你的项目根目录下就有了一个 requirements.txt 文件,内容可能如下:

    langchain==0.1.16 langchain-community==0.0.34 requests==2.28.2 ...
  2. requirements.txt 文件安装依赖 当其他人拿到你的项目后,他们只需:

    • 创建并激活自己的虚拟环境。
    • 运行以下命令来安装所有必需的包:
      (venv) $ pip install -r requirements.txt

    这样就能完美复制你的开发环境。


五、重要提示与常见问题 (FAQ)

  1. 应该把 venv 文件夹提交到 Git 吗? 绝对不要!

    • 它非常大,包含了很多二进制文件。
    • 它与操作系统和 Python 版本绑定,在别人的电脑上可能无法使用。
    • 它可以通过 requirements.txt 文件轻松重建。 你应该在项目的 .gitignore 文件中加入一行 venv/,以防止 Git 跟踪它。
  2. 为什么我的 VS Code/PyCharm 找不到我安装的包? 你需要告诉你的 IDE 使用虚拟环境中的 Python 解释器,而不是全局的。

    • VS Code:按 Ctrl+Shift+P (或 Cmd+Shift+P),搜索 “Python: Select Interpreter”,然后选择你的 ./venv/bin/python
    • PyCharm:在 Settings/Preferences -> Project: [your_project_name] -> Python Interpreter 中,添加一个新的解释器,并指向你的 ./venv/bin/python
  3. venv vs virtualenv vs conda 有什么区别?

    • venv:Python 3.3+ 内置的标准库,轻量,纯粹用于管理 Python 包依赖。是目前社区的通用首选
    • virtualenvvenv 的前身和灵感来源,是一个第三方包。在旧版 Python 中(3.3 之前)是必须的,现在除非有特殊需求,否则 venv 就足够了。
    • conda:来自 Anaconda 发行版,是一个更强大的环境管理器。它不仅能管理 Python 包,还能管理 Python 解释器本身(例如轻松切换 Python 3.8 和 3.10),甚至可以管理非 Python 的软件(如 C++ 库、CUDA)。在数据科学领域非常流行,但对于纯粹的 Web 开发或脚本编写,venv 更为轻便。

总结

将使用虚拟环境内化为你的开发习惯,就像开车前系好安全带一样。

核心流程回顾:

  1. cd my-project
  2. python -m venv venv
  3. source venv/bin/activate (或 .\venv\Scripts\activate)
  4. pip install ...
  5. pip freeze > requirements.txt (定期更新)
  6. deactivate (当你完成工作时)

掌握了它,你就能告别依赖冲突,让你的 Python 项目变得干净、可复现和专业。

uv

好的,我们来深入、全面地聊一聊 uv 这个在 Python 社区引起巨大轰动的新工具。

uv 不仅仅是一个“快一点的 pip”,它代表了 Python 工具链发展的一个新方向:统一与性能


uv 是什么?一句话定义

uv 是一个用 Rust 编写的、速度极快的 Python 包安装器、解析器和虚拟环境管理器,旨在成为 pippip-toolsvenv 等工具的统一、高速替代品。

它由 ruff(一个用 Rust 写的超快 Python Linter)的同一个团队 Astral 开发,这为其性能和质量提供了强大的信誉背书。


核心理念:为什么需要 uv

uv 出现之前,一个标准的 Python 项目工作流通常需要多个工具的组合:

  1. 环境创建:使用 python -m venv .venv
  2. 包安装:使用 pip install -r requirements.txt
  3. 依赖锁定:使用 pip-toolspip-compile)或者手动 pip freeze
  4. 环境管理:激活/停用脚本

这个流程行之有效,但存在几个痛点:

  • 速度慢pip 在解析复杂的依赖关系或安装大量包时可能会非常慢。python -m venv 创建环境也需要几秒钟。
  • 工具碎片化:你需要学习和管理多个独立的工具 (pip, venv, pip-tools)。
  • 体验不一致:不同工具的命令行接口和行为各不相同。

uv 的目标就是用一个统一、高性能的工具来解决以上所有问题。


uv 的核心特性与“杀手级”功能

1. 极致的速度 (The #1 Selling Point)

这是 uv 最直观的优势。它之所以快,主要得益于:

  • Rust 实现:Rust 提供了接近 C/C++ 的性能,同时保证了内存安全,使其能够高效地执行 CPU 密集型任务(如依赖解析)和 I/O 密集型任务(如下载和解压)。
  • 高度并行化uv 在下载和构建包时会尽可能地并行处理。
  • 智能的全局缓存:这是它的秘密武器。

2. 全局缓存 (Shared Global Cache)

pip 默认的缓存是每个用户一个,但 uv 的缓存设计更进一步。

  • 下载一次,到处使用:当你使用 uv 在任何一个虚拟环境中安装一个包(比如 requests==2.31.0)时,uv 会将它下载并构建到全局缓存目录中。
  • 硬链接/写时复制:当你需要在另一个新的虚拟环境中安装同样版本requests 时,uv 不会重新下载或构建。它会直接从全局缓存中通过硬链接(或在不支持的系统上使用写时复制/直接复制)“链接”到你的虚拟环境的 site-packages 目录。
  • 结果:创建新环境和安装已有依赖的速度从分钟级降低到亚秒级。这极大地提升了 CI/CD 流程和本地开发的效率。

3. 一体化工具链 (Integrated Toolchain)

uv 将多个工具的功能整合到同一个命令行接口下:

  • uv venv: 替代 python -m venv,创建虚拟环境的速度快得惊人。
  • uv pip install/uninstall: 替代 pip install/uninstall,用于安装和卸载包。
  • uv pip compile: 替代 pip-toolspip-compile,用于将 requirements.inpyproject.toml 文件编译成锁定的 requirements.txt
  • uv pip freeze: 替代 pip freeze
  • uv pip list: 替代 pip list

这种统一性大大简化了开发者的心智负担。

4. “即插即用”的兼容性 (Drop-in Compatibility)

uv 的设计非常注重与现有生态的兼容性:

  • 它完全支持 requirements.txtpyproject.toml (PEP 621) 文件。
  • 它的命令行接口有意设计得与 pip 非常相似(例如 uv pip install),让用户可以无缝切换。
  • 你可以在现有项目上直接开始使用 uv,而无需对项目结构做任何大的改动。

如何安装和使用 uv

安装

官方推荐使用 pipx 来安装,因为 pipx 可以将命令行工具安装在独立的环境中,避免污染全局 Python 环境。

# 推荐方式 pipx install uv # 或者使用 pip pip install uv # 验证安装 uv --version

核心使用场景示例

让我们模拟一个完整的项目工作流:

场景 1:替代 venv + pip

# 1. 创建虚拟环境 (速度比 'python -m venv' 快几个数量级) # 它会自动在当前目录创建 .venv uv venv # 2. 激活环境 (激活方式和 venv 完全一样) # macOS / Linux source .venv/bin/activate # Windows # .venv\Scripts\activate # 3. 安装包 (感受飞一样的速度) (.venv) $ uv pip install "fastapi[all]" black ruff # 4. 从 requirements.txt 文件安装 (.venv) $ echo "django==5.0" > requirements.txt (.venv) $ uv pip install -r requirements.txt # 5. 生成 requirements.txt (.venv) $ uv pip freeze > requirements.txt # 6. 查看已安装的包 (.venv) $ uv pip list

场景 2:替代 pip-tools 进行依赖锁定

这是更现代、更可靠的依赖管理方式。

  1. pyproject.toml 中定义你的顶层依赖:

    # pyproject.toml [project] name = "my-awesome-project" version = "0.1.0" dependencies = [ "fastapi>=0.100.0", "pydantic>=2.0", ] [project.optional-dependencies] dev = [ "ruff", "pytest", ]
  2. 使用 uv pip compile 生成锁定的 requirements.txt

    # 激活虚拟环境后运行 # 生成生产环境的依赖锁文件 (.venv) $ uv pip compile pyproject.toml -o requirements.txt # 生成开发环境的依赖锁文件 (.venv) $ uv pip compile pyproject.toml --extra dev -o requirements-dev.txt

    uv 会解析所有子依赖,并生成一个包含所有包及其哈希值的、完全固定的文件,确保了构建的可复现性。

  3. 在任何地方(比如 CI/CD)安装锁定的依赖:

    (.venv) $ uv pip install -r requirements.txt

uv 的现状与局限性

现状

  • 生产可用:对于其核心功能(安装、环境创建、依赖解析),uv 已经被认为是生产环境可用的。包括 Ryetox 在内的许多项目已经将其集成作为后端。
  • 快速迭代:Astral 团队正在以极快的速度为其添加新功能和修复问题。

局限性

  1. 不管理 Python 版本:和 venv 一样,uv 不负责安装和管理 Python 解释器本身。你需要在系统上先安装好想要的 Python 版本。这一点与 condapyenv 不同。pyenv + uv 是一个非常流行的组合。
  2. 尚不具备完整的项目管理功能:像 PoetryPDM 那样的 poetry add <package> 命令(它会自动修改 pyproject.toml 文件)在 uv尚未实现。目前你仍然需要手动编辑 pyproject.tomlrequirements.in 文件。这是 uv 路线图上的重要一环。
Last updated on