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 的关系 ​

很多初学者把 python 和 pip 当成两个独立工具,其实 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 list 和 pip 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.txt 或 pyproject.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 确认包是否安装;然后检查包名和导入名是否一致,以及当前工作目录和模块路径是否正确。

关联知识点 ​