第3章 Python版本管理与虚拟环境

聊可重复性,绕不开Python版本和依赖环境。你可能遇到过这种情况:把一个项目丢给同事,他那边跑不起来,报个奇怪的语法错误——结果发现他用的是Python 3.12,你用的是3.8。嗯,这种事我碰过不止一次。

为什么需要版本管理?

说白了,不同项目依赖不同Python版本。比如我去年维护的一个老项目,跑在Python 2.7上,而新项目已经用上了3.10。同时开发时,光是切换系统默认Python就够头疼的。更别说还有包依赖冲突——项目A要numpy 1.19,项目B要numpy 1.26。没有隔离环境,你只能二选一。

所以,我们需要两样东西:Python版本管理器和虚拟环境工具。前者让你随时切换全局Python版本,后者让你为每个项目创建独立的环境。

pyenv:轻量级Python版本管理

我个人的习惯是用pyenv来管理Python版本。它只做一件事——安装和切换不同版本的Python,不碰你系统的包管理器。

安装pyenv

# macOS / Linux
curl https://pyenv.run | bash

# 然后将以下内容添加到 ~/.bashrc 或 ~/.zshrc
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

常用命令一览

命令作用
pyenv install --list列出所有可安装的Python版本
pyenv install 3.9.18安装指定版本
pyenv versions查看已安装的版本列表
pyenv global 3.9.18设置全局默认版本
pyenv local 3.8.10在当前目录设置局部版本(生成.python-version文件)
pyenv shell 3.11.0临时为当前shell设置版本(优先级最高)

小技巧:如果你和我一样经常在不同项目间切换,建议在每个项目根目录执行 pyenv local 版本号。这样cd进目录自动切换,省心。

conda:重度依赖环境的最佳选择

pyenv只管Python版本,不管依赖。而conda不仅管Python版本,还能管理所有包(包括非Python的库)。尤其适合做AI项目的同学——TensorFlow、PyTorch、CUDA驱动,这些依赖关系复杂,conda处理得比pip强太多。

安装Miniconda(精简版)

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh

环境创建与使用

# 创建一个指定Python版本的环境
conda create -n myproject python=3.9

# 激活环境
conda activate myproject

# 安装包(自动解决依赖冲突)
conda install numpy pandas scikit-learn

# 导出环境描述文件(可复现)
conda env export > environment.yml

# 从文件创建同样环境
conda env create -f environment.yml

# 退出环境
conda deactivate

# 列出所有环境
conda env list

注意:我曾经把环境文件直接提交到Git仓库,结果队友在不同系统上运行,因为CUDA版本不同全崩了。我现在会同时输出两个文件:environment.yml(完整依赖)和requirements.txt(纯pip格式),再在README里说明怎么用。

pyenv vs conda:何时用哪个?

这不是二选一的问题。你可以同时用它们——pyenv管理Python版本,conda管理虚拟环境和包。但为了减少心智负担,我建议按场景选择:

场景推荐工具理由
纯Python脚本项目(web、爬虫、小工具)pyenv + venv/pip轻量,快速,无需conda
AI/ML项目(TensorFlow、PyTorch、GPU相关)conda自动处理CUDA、cudnn等非Python依赖
团队协作、需要严格复现conda + environment.yml锁定所有层级依赖
快速原型、尝试多个Python版本pyenv 切换 + 临时环境版本切换秒级完成

核心工作流(含SVG流程图)

下面这张图概括了我每次新建AI项目时的操作路径。你按这个走,基本不会掉坑。

Python版本管理与虚拟环境工作流程 项目需求分析 pyenv install 版本 conda create -n 项目名 安装依赖(conda/pip) 导出 environment.yml 关键注意事项 1. pyenv local 优先于 global 2. conda环境名避免用空格 3. 导出前先 conda clean -a 4. 环境文件必须和代码一起提交 5. 不同OS可能需要调整CUDA版本 6. 记得在README里写使用步骤 前置准备 • 安装 pyenv 或 pyenv-win • 安装 Miniconda/Anaconda • 设置 shell 初始化脚本 • 确保网络能访问镜像源 • 准备好 requirements.txt 模板

避坑指南

  • 我曾经在Mac上用了系统自带的Python,结果升级macOS后项目全挂。从那以后我坚持用pyenv安装独立Python,跟系统彻底解耦。
  • 我建议每个项目都从零创建虚拟环境,不要复用别人的环境。哪怕只是改了一个包版本,也重新生成一次environment.yml。
  • 为什么会这样?因为pip/pipenv的依赖解析是贪心的,它只保证安装时满足约束,但不保证下次安装得到相同环境。conda的solver相对严格,但也不是100%可复现——所以必须锁版本。

终极建议:如果你做AI项目,无脑选「pyenv切换Python版本 + conda管理环境 + pip安装缺失包」。这个组合我用了一年多,团队里再没出现过"在我电脑上能跑啊"的鬼故事。

好了,关于版本管理和虚拟环境就先聊这么多。剩下的核心是:每次运行都确保环境是全新创建的,并且锁定文件跟着代码走。你按这流程走,可重复性至少提升80%。