Skip to content

Python环境与包管理

Python 项目最容易出问题的地方往往不是语法,而是环境和依赖。同一台电脑上可能有多个 Python 解释器,同一个包也可能有多个版本;如果不隔离环境,就会出现“我电脑能跑、你电脑不能跑、服务器也不能跑”的问题。

学完本页后,你应该能做到:

  1. 说清楚 Python 解释器、pip、虚拟环境、项目依赖之间的关系。
  2. 会在 Windows、macOS、Linux 上创建和激活虚拟环境。
  3. 知道 pip install 到底把包装到了哪里。
  4. 会用 requirements.txt 复现环境。
  5. 理解 pyproject.toml、Poetry、uv 这类现代包管理工具解决什么问题。
  6. 能排查“包安装了但导入失败”“pip 装错环境”“版本冲突”“AI 环境 CUDA 不匹配”等问题。

为什么必须理解环境

一个 Python 项目能运行,至少依赖四层东西:

mermaid
flowchart TD
    A["操作系统"] --> B["Python 解释器"]
    B --> C["虚拟环境 venv"]
    C --> D["第三方依赖包"]
    D --> E["项目代码"]

每层都可能出问题:

层级常见问题
操作系统Windows/Linux 路径不同、权限不同、动态库不同
Python 解释器版本不同,语法或标准库能力不同
虚拟环境没激活、激活错、删了依赖
第三方包版本冲突、装到全局、缺少二进制依赖
项目代码import 路径错误、配置缺失

商业项目里,环境管理的目标不是“本机能跑”,而是让同事、测试机、生产容器都能稳定复现。

Python、pip、venv 的关系

很多初学者把 pythonpip 当成两个独立工具,其实 pip 总是属于某个 Python 解释器。

mermaid
flowchart TD
    A["Python 3.10 解释器"] --> B["它自己的 pip"]
    A --> C["site-packages 依赖目录"]
    D["Python 3.12 解释器"] --> E["它自己的 pip"]
    D --> F["另一个 site-packages 依赖目录"]

如果你运行:

bash
pip install requests

你必须确认这个 pip 属于当前项目要用的 Python。否则可能出现:安装成功了,但运行代码时仍然 ModuleNotFoundError

更稳的写法是:

bash
python -m pip install requests

含义:用当前这个 python 去执行它绑定的 pip 模块。这样能避免 pip 指向另一个解释器。

查看当前 Python 环境

查看版本:

bash
python --version
python -m pip --version

查看解释器路径:

bash
python -c "import sys; print(sys.executable)"

查看包搜索路径:

bash
python -c "import sys; print('\n'.join(sys.path))"

Windows 上如果安装了多个版本,可以使用:

bash
py -0
py -3.11 --version
py -3.12 --version

排查环境问题时,最重要的不是看命令有没有成功,而是看“当前命令到底用了哪个解释器”。

虚拟环境解决什么问题

假设两个项目依赖同一个库的不同版本:

项目依赖
旧后台系统fastapi==0.95.0
新 AI 服务fastapi==0.115.0

如果都装在全局环境,后安装的版本可能覆盖前面的版本,导致旧项目突然不能运行。

虚拟环境就是给每个项目创建一套独立依赖目录。

mermaid
flowchart TD
    A["全局 Python"] --> B["项目 A .venv"]
    A --> C["项目 B .venv"]
    B --> D["fastapi 0.95"]
    C --> E["fastapi 0.115"]

注意:虚拟环境通常不会复制一整个 Python,它会引用或链接基础解释器,再创建独立的可执行入口和依赖目录。

创建虚拟环境

在项目根目录执行:

bash
python -m venv .venv

推荐命名为 .venv,原因:

  1. IDE 容易识别。
  2. 放在项目根目录方便定位。
  3. .gitignore 很容易排除。

激活虚拟环境:

bash
# Windows PowerShell
.venv\Scripts\Activate.ps1

# Windows cmd
.venv\Scripts\activate.bat

# macOS / Linux
source .venv/bin/activate

退出虚拟环境:

bash
deactivate

激活后再检查:

bash
python -c "import sys; print(sys.executable)"
python -m pip --version

如果路径里出现当前项目的 .venv,说明环境正确。

Windows PowerShell 激活失败

如果 PowerShell 提示脚本执行策略禁止,可能会看到类似错误:

text
cannot be loaded because running scripts is disabled on this system

可以对当前用户放开执行策略:

powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

然后重新激活:

powershell
.venv\Scripts\Activate.ps1

这不是 Python 错误,而是 Windows PowerShell 的安全策略。

pip 常用命令

bash
# 安装依赖
python -m pip install requests

# 安装指定版本
python -m pip install fastapi==0.115.0

# 升级包
python -m pip install -U requests

# 查看已安装包
python -m pip list

# 查看某个包详情
python -m pip show requests

# 导出依赖
python -m pip freeze > requirements.txt

# 安装依赖文件
python -m pip install -r requirements.txt

pip listpip freeze 的区别:

命令适合用途
pip list人看当前装了什么
pip freeze生成可复现依赖清单

requirements.txt

requirements.txt 用于记录项目依赖,便于别人复现环境。

text
fastapi==0.115.0
uvicorn==0.30.6
requests==2.32.3

别人拿到项目后:

bash
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt

为什么要锁版本?

如果只写:

text
fastapi
requests

今天安装和三个月后安装可能得到不同版本。新版本可能改行为、删 API、改依赖,导致项目突然跑不起来。

依赖复现流程:

mermaid
flowchart TD
    A["开发者安装依赖"] --> B["确认项目能运行"]
    B --> C["pip freeze 导出 requirements.txt"]
    C --> D["提交代码仓库"]
    D --> E["同事或服务器创建 .venv"]
    E --> F["pip install -r requirements.txt"]
    F --> G["得到相同依赖版本"]

requirements 的局限

requirements.txt 简单直接,但有几个局限:

  1. 不区分直接依赖和间接依赖。
  2. 不天然区分开发依赖和生产依赖。
  3. 没有统一的项目元信息。
  4. 依赖冲突时不如现代工具清晰。

小脚本、简单项目用它足够。中大型项目可以考虑 pyproject.toml

pyproject.toml 是什么

pyproject.toml 是 Python 现代项目配置文件,常用于描述项目元信息、依赖、构建工具、格式化工具、类型检查工具配置。

示例:

toml
[project]
name = "asset-api"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
    "fastapi==0.115.0",
    "uvicorn==0.30.6",
    "requests==2.32.3",
]

[tool.pytest.ini_options]
testpaths = ["tests"]

常见工具:

工具特点
pip + venv标准、简单、通用
Poetry项目管理完整,依赖解析和 lock 文件成熟
PDM基于现代标准,适合包管理
uv速度很快,适合新项目和 CI
conda科学计算、AI、CUDA、二进制依赖场景常见

不要为了“看起来高级”强行上复杂工具。团队已有规范就按团队规范;没有规范时,小项目 venv + requirements.txt 就够用。

依赖冲突是怎么来的

依赖冲突通常不是你直接装的两个包冲突,而是它们的间接依赖冲突。

mermaid
flowchart TD
    A["你的项目"] --> B["Package A"]
    A --> C["Package B"]
    B --> D["common-lib >=1.0,<2.0"]
    C --> E["common-lib >=2.0,<3.0"]
    D --> F{"版本范围是否有交集"}
    E --> F
    F -->|没有| G["依赖解析失败"]

排查命令:

bash
python -m pip check
python -m pip show 包名

解决思路:

  1. 先确认业务是否真的需要两个冲突包。
  2. 查看包的兼容版本范围。
  3. 升级或降级其中一个包。
  4. 必要时更换库或拆分服务。
  5. 不要盲目 pip install -U,否则可能引入更多变化。

import 路径和包结构

项目结构示例:

text
asset_api/
  app/
    __init__.py
    main.py
    services/
      __init__.py
      asset_service.py
  requirements.txt

运行时,Python 会根据 sys.path 查找模块。常见错误:

text
ModuleNotFoundError: No module named 'app'

可能原因:

  1. 当前工作目录不在项目根目录。
  2. 没有激活虚拟环境。
  3. 包结构缺少 __init__.py
  4. IDE 配置的解释器不是项目 .venv
  5. 用了相对导入,但运行方式不对。

推荐从项目根目录运行:

bash
python -m app.main

而不是随便进入某个子目录后运行脚本。

商业 Demo:从零创建 FastAPI 项目环境

创建目录:

bash
mkdir asset-api
cd asset-api
python -m venv .venv

激活环境:

bash
# Windows PowerShell
.venv\Scripts\Activate.ps1

# macOS / Linux
source .venv/bin/activate

安装依赖:

bash
python -m pip install fastapi==0.115.0 uvicorn==0.30.6
python -m pip freeze > requirements.txt

创建 main.py

python
from fastapi import FastAPI

app = FastAPI(title="asset-api")


@app.get("/health")
def health():
    return {"status": "UP"}

启动:

bash
uvicorn main:app --reload

验证:

text
http://127.0.0.1:8000/health
http://127.0.0.1:8000/docs

交给同事时,只需要提交:

text
main.py
requirements.txt
.gitignore

不要提交:

text
.venv/
__pycache__/
.pytest_cache/

AI 项目环境为什么更容易炸

AI 项目通常涉及 Python、PyTorch、CUDA、显卡驱动、操作系统动态库。任何一层不匹配都可能失败。

mermaid
flowchart TD
    A["显卡驱动"] --> B["CUDA 运行时"]
    B --> C["PyTorch 对应 CUDA 版本"]
    C --> D["Python 版本"]
    D --> E["Transformers / Embedding / LLM 依赖"]

常见问题:

现象可能原因
torch.cuda.is_available()False驱动、CUDA、PyTorch 版本不匹配
安装 PyTorch 很慢下载源慢或包很大
ImportError: DLL load failedWindows 动态库缺失或版本不兼容
向量库安装失败需要编译工具或特定 Python 版本
同事能跑自己不能跑Python、小版本依赖、系统库不同

AI 项目建议:

  1. 明确 Python 版本,例如 3.10
  2. 明确 PyTorch 安装命令,不要只写 pip install torch
  3. 记录 CUDA 版本和显卡驱动要求。
  4. 优先使用 lock 文件或容器镜像复现环境。
  5. 把模型文件、向量库数据和代码依赖分开管理。

Docker 和虚拟环境的关系

Docker 不是替代虚拟环境的同一个概念。

能力venvDocker
隔离 Python 包可以可以
隔离操作系统依赖不可以可以
复现部署环境一般更强
启动成本较高
适合场景本地开发部署、CI、复杂依赖

很多团队会这样组合:

  1. 本地开发用 .venv
  2. 提交 requirements.txtpyproject.toml
  3. CI 和生产用 Docker 构建镜像。

这样既保持本地开发轻量,又保证部署环境可复现。

常见问题排查

包安装成功但 import 失败

按这个顺序查:

mermaid
flowchart TD
    A["import 失败"] --> B["查看 python 路径"]
    B --> C["查看 pip 路径"]
    C --> D{"是否同一个 .venv"}
    D -->|否| E["激活正确虚拟环境或用 python -m pip"]
    D -->|是| F["pip show 包名"]
    F --> G{"包是否真的安装"}
    G -->|否| H["安装到当前环境"]
    G -->|是| I["检查模块名是否和包名不同"]

例如包名是 beautifulsoup4,导入名是:

python
from bs4 import BeautifulSoup

包名和导入名不总是一致。

pip 安装到了错误的 Python

使用:

bash
python -m pip --version
python -c "import sys; print(sys.executable)"

确认两个路径都在当前项目 .venv 下。

requirements 安装失败

排查:

  1. Python 版本是否满足依赖要求。
  2. 操作系统是否支持该包。
  3. 是否需要 C/C++ 编译工具。
  4. 是否下载源不可用。
  5. 是否有版本冲突。

可以尝试:

bash
python -m pip install -r requirements.txt -i https://pypi.org/simple
python -m pip check

虚拟环境要不要提交

不要提交 .venv。原因:

  1. 体积大。
  2. 包含本机绝对路径。
  3. 跨系统不可复用。
  4. 会污染仓库。

提交依赖清单即可。

.gitignore 示例

gitignore
.venv/
__pycache__/
*.pyc
.pytest_cache/
.mypy_cache/
.ruff_cache/
.env

注意:.env 里经常有数据库密码、Token、模型 Key,不要提交。

开发建议

  1. 每个项目单独创建虚拟环境。
  2. 优先使用 python -m pip,避免 pip 指向错误环境。
  3. 依赖变更后及时更新依赖文件。
  4. 不要把 .venv、缓存、密钥提交到仓库。
  5. 项目 README 写清 Python 版本、启动命令、依赖安装命令。
  6. AI 项目额外记录 CUDA、PyTorch、模型文件位置。
  7. 生产部署尽量使用容器或自动化脚本,避免手工在服务器上补包。

面试标准回答

Python 虚拟环境解决什么问题?

标准回答:虚拟环境为每个项目创建独立的依赖目录,避免不同项目依赖版本互相污染。例如旧项目需要 FastAPI 0.95,新项目需要 FastAPI 0.115,如果都装全局环境就可能冲突。虚拟环境能让每个项目使用自己的解释器入口和 site-packages。

为什么推荐 python -m pip?

标准回答:因为 pip 可能指向另一个 Python 解释器,尤其是多版本 Python 或虚拟环境没激活时。python -m pip 表示使用当前这个 python 对应的 pip,可以减少包安装到错误环境的问题。

requirements.txt 有什么作用?

标准回答:它记录项目依赖及版本,别人或服务器可以通过 pip install -r requirements.txt 复现环境。锁定版本能减少由于依赖升级导致的不可预期问题。

pyproject.toml 和 requirements.txt 有什么区别?

标准回答:requirements.txt 更像依赖安装清单,简单直接;pyproject.toml 是现代 Python 项目配置文件,可以描述项目元信息、依赖、构建系统和工具配置,更适合中大型项目和包发布。

包安装了但 import 失败怎么查?

标准回答:先查当前运行的 python 路径和 python -m pip --version 是否属于同一个虚拟环境;再用 pip show 确认包是否安装;然后检查包名和导入名是否一致,以及当前工作目录和模块路径是否正确。

关联知识点