适用读者:环境建了删、删了建,但从没"导出给别人重建"过的人。
前置:S10-B02。
实测环境:Python 3.12.3 + venv(Conda 命令为官方文档口径,机制与 venv 一致)。
覆盖旧文:A-1415(17) A-1416(25) A-1417(14) A-1418(32) A-1419(18) A-1420(15) = 121 点。
覆盖扩展:E-S10-004(environment.yml导出与--no-builds)。
上一篇:S10-B02 · Conda 安装与换源:三平台 + 国内镜像
下一篇:S10-B04 · FastAPI 入门。
1. 一句话结论
环境的完整生命周期只有五步:创建 → 激活 → 安装 → 导出 → 重建。其中"导出与重建"决定了这个环境是可复现的资产,还是一次性的消耗品。
create ─► activate ─► install ─► export ─► recreate(另一台机器)
│
└─ 这一步跑通,才算"可复现"
2. 实测:完整走一遍(venv 替代,机制相同)
$ python3 -m venv .venv
$ . .venv/bin/activate
$ python -V
Python 3.12.3
$ pip install -q "httpx==0.27.2"
$ python -c "import httpx; print(httpx.__version__)"
0.27.2
$ pip freeze | head -5
anyio==4.16.0
certifi==2026.10.23
h11==0.16.0
httpcore==1.0.9
httpx==0.27.2
然后在新环境用导出文件重建(实测):
$ pip freeze > req-locked.txt
$ python3 -m venv .venv2 && . .venv2/bin/activate
$ pip install -q -r req-locked.txt
$ python -c "import httpx; print('重建后 httpx', httpx.__version__)"
重建后 httpx 0.27.2
关键观察:pip freeze 输出的是完整依赖树(anyio、httpcore、h11、certifi 都是 httpx 的传递依赖),且版本精确到 patch——这才是可复现的前提。
3. Conda 版的生命周期命令
| 步骤 | 命令 | 说明 |
|---|---|---|
| 创建 | conda create -n myenv python=3.11 |
指定解释器版本(关键) |
| 激活 | conda activate myenv |
需要 conda init 已生效 |
| 安装 | conda install numpy / pip install requests |
先 conda 后 pip |
| 查看 | conda list |
当前环境已装包 |
| 导出(跨平台) | conda env export --no-builds > environment.yml |
--no-builds 去掉平台相关 build 号 |
| 导出(仅直接依赖) | conda env export --from-history |
更干净,适合手写维护 |
| 重建 | conda env create -f environment.yml |
在另一台机器 |
| 删除 | conda env remove -n myenv |
不会删错 base(会拒绝) |
| 列表 | conda env list |
看所有环境与路径 |
--no-builds 为什么重要(E-S10-004):默认导出会包含 numpy=1.26.4=py311h5f7f6f0_0 这类 build 串,跨平台/跨 CUDA 版本会装不上;去掉 build 号只锁版本,兼容性好得多。
3.1 三个导出策略对比
| 策略 | 命令 | 优点 | 缺点 |
|---|---|---|---|
| 全量(含 build) | conda env export |
完全一致 | 换平台必失败 |
| 去 build | conda env export --no-builds |
跨平台可用 | 二进制可能不同 |
| 仅历史(直接依赖) | conda env export --from-history |
干净、易读 | 传递依赖不锁 |
判据:交付给他人 → --no-builds;自己长期复现 → 全量;写进仓库的 environment.yml → --from-history + 单独锁文件。
4. 判断"环境真的可复现"的三条标准
| # | 标准 | 验证方式 |
|---|---|---|
| 1 | 解释器版本明确 | environment.yml 里有 python=3.x |
| 2 | 依赖版本精确 | 有锁文件(pip freeze 或 conda list --explicit) |
| 3 | 在干净环境重建成功 | 别人(或 CI)跑一遍 create -f + 启动服务 |
只有第 3 条能证明可复现——前两条只是"看起来锁了"。
5. 五个误区
| 误区 | 真相 |
|---|---|
"conda activate 报错就是没装好" |
多是 conda init 没生效(B02 §2.4) |
"导出 environment.yml 就够了" |
含 build 号的导出换平台会失败 |
| "删环境会删掉包缓存" | 缓存(pkgs)独立,需 conda clean 清 |
| "base 环境可以随便装" | base 只放 conda 自身,开发另建环境 |
| "venv 与 conda 可以随便混" | 会出现"环境来源不明",团队要统一一种 |
6. 自检
pip freeze为什么会输出一堆你没直接装的包?--no-builds与--from-history分别适合什么场景?- 怎么证明一个环境"真的可复现"?
conda env remove与conda clean的区别?- 为什么开发不该用 base 环境?
7. 下一篇
S10-B04 · FastAPI 入门:类型即文档
环境就绪后,下一篇写第一个 API。FastAPI 的特点是"类型标注直接变成校验与文档"——会给出真实启动、真实 422 校验明细、真实 OpenAPI 输出。
本篇属于系列《S10 · Python 语言与环境》。旧文来源:A-1415–A-1420;扩展点 E-S10-004。venv 全流程为 2026-11-05 实测。