Python环境管理指南
Table of Contents
Python环境管理指南 #
在 Linux (Ubuntu 22.04) 下开发 Python 项目时,环境管理往往是新手的噩梦。系统自带 Python 版本不够用、依赖冲突、pip 报错……这些问题层出不穷。
本文将总结一套标准化的环境管理思路,并解答四个核心问题:
- 版本管理:系统原生Python不够用,我想安装高版本python,如何管理?
- 新项目:如何从 0 开始管理依赖?
- 老项目:接手别人的项目,如何快速跑起来?
- 故障排查:遇到环境 Bug(如配置冲突)如何系统性定位?
一、如何管理多版本Python? #
很多混乱源于搞不清工具的职责。我们先理清 pyenv、pip、poetry 和 uv 的关系:
- Python 版本管理:pyenv 解决的问题:Ubuntu 22.04 自带 Python 3.10,但你想用 Python 3.12,或者不同项目需要不同版本。 原则:永远不要污染/修改系统的 /usr/bin/python3。 方案:使用 pyenv 在用户目录下安装多个隔离的 Python 版本。
推荐工具:pyenv
-
安装pyenv
curl https://pyenv.run | bash # 在~/.bashrc或~/.zshrc中添加: # export PYENV_ROOT="$HOME/.pyenv" # export PATH="$PYENV_ROOT/bin:$PATH" # eval "$(pyenv init -)" -
安装特定Python版本
pyenv install 3.12.0 # 安装Python 3.12 pyenv install 3.11.5 # 安装Python 3.11 pyenv versions # 查看已安装版本 -
版本切换
pyenv global 3.12.0 # 设置全局默认版本 pyenv local 3.11.5 # 设置当前目录版本(创建.python-version文件) -
** 避免的做法**
- 不要从源码编译安装到
/usr/local - 不要用
apt install python3.x安装非官方版本 - 不要修改系统
/usr/bin/python3的软链接
- 不要从源码编译安装到
2. 包/依赖管理工具对比 #
有了 Python 解释器后,我们需要安装包(如 FastAPI, Pandas)。
| 工具 | 定位 | 优缺点 | 适用场景 |
|---|---|---|---|
| pip | 基础安装器 | 优点:系统预装,简单。缺点:不解决依赖冲突,无锁文件,无环境隔离(需配合 venv)。 | 简单的脚本,或在 Docker 容器内。 |
| Poetry | 全能管家 | 优点:集成了虚拟环境、依赖解析、打包发布。生成的 poetry.lock 保证多人开发环境一致。缺点:速度较慢,略显厚重。 |
生产级项目,需要严格版本控制。 |
| uv | 极速新秀 (推荐) | 优点:Rust 编写,速度极快(比 pip/poetry 快 10-100 倍),兼容 pip 和 poetry 工作流。缺点:生态正在快速完善中。 | 现代开发首选,追求效率。 |
三、 故障排查实战:配置冲突引发的惨案 #
问题描述:
在使用 pre-commit 或 pip 安装包时,报错:
ERROR: Cannot set --home and --prefix together
这是环境管理中非常经典的一个错误。下面我们复盘整个排查过程,学习排查思路。
1. 排查思路 (SOP) #
遇到环境问题,按以下顺序检查:
- 读报错:分析互斥参数。
- 查环境:
env | grep PYTHON。 - 查配置:
pip config list(最常被忽略的一步)。 - 查路径:
which python和sys.path。
2. 详细排查过程 #
第一阶段:分析报错 #
错误信息 Cannot set --home and --prefix together 说明 pip 在执行时,接收到了两个冲突的指令:
--home:指定安装到用户目录(pre-commit 内部常用)。--prefix或target:指定安装到特定前缀。 结论:必然有一个参数是隐式生效的(比如通过全局配置文件)。
第二阶段:检查环境变量 #
执行 env | grep -E "PYTHON|HOME|PREFIX":
PYTHON_HOME=/usr/local
PYTHONPATH=/usr/local/lib/python3.12/site-packages
- 分析:这里发现了坏味道。
PYTHON_HOME和PYTHONPATH最好不要在全局(.bashrc)中设置,它们会污染所有虚拟环境。但这通常导致ModuleNotFoundError,而不是参数冲突。
第三阶段:检查 pip 全局配置(关键!) #
执行 python3 -m pip config list,结果发现:
global.target='/home/narwal/.local/lib/python3.12/site-packages'
真相大白!
- 原因:你在全局配置文件(
~/.config/pip/pip.conf)中设置了target。 - 冲突点:当你运行
pre-commit时,它会创建一个隔离的虚拟环境,并试图使用--home或类似机制安装包。但你的全局配置强行插入了一个target参数,导致 pip 认为你要同时安装到两个不同的地方,从而报错。
3. 修复方案 #
核心原则:pip 的全局配置应尽可能保持纯净。
- 定位文件:
find ~/.config/pip ~/.pip /etc/pip* -name "pip.conf" # 结果:/home/narwal/.config/pip/pip.conf - 移除冲突配置:
删除
target行,仅保留镜像源配置。[global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple # target = ... <-- 删除这行 - 清理缓存:
rm -rf ~/.cache/pre-commit
四、 避坑指南:环境配置红线 #
为了避免未来再踩坑,请遵守以下 “红线”:
- 禁止设置全局
target或prefix: 永远不要在pip.conf中设置这两个参数,它们会破坏虚拟环境的隔离性。 - 慎用全局
PYTHONPATH: 不要在.bashrc中export PYTHONPATH=...。如果项目需要路径,请在项目级.env文件或 IDE 配置中设置。 - 不要用
sudo pip: 这会通过系统 Python 安装包,可能搞挂 Ubuntu 的系统工具(如apt)。 - 始终使用虚拟环境: 无论是 venv, poetry 还是 uv,确保你安装的包只属于当前项目。
推荐的极简 pip 配置 #
只配置镜像源和超时,其他交给项目工具管理:
# ~/.config/pip/pip.conf
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
timeout = 120
总结:Linux 下的 Python 环境管理并不复杂,核心在于隔离。用 pyenv 隔离版本,用 uv/poetry 隔离依赖,保持全局配置的纯净,大部分问题都能迎刃而解。