Skip to main content
  1. Posts/

Python环境管理指南

·313 words·2 mins

Python环境管理指南 #

在 Linux (Ubuntu 22.04) 下开发 Python 项目时,环境管理往往是新手的噩梦。系统自带 Python 版本不够用、依赖冲突、pip 报错……这些问题层出不穷。

本文将总结一套标准化的环境管理思路,并解答四个核心问题:

  1. 版本管理:系统原生Python不够用,我想安装高版本python,如何管理?
  2. 新项目:如何从 0 开始管理依赖?
  3. 老项目:接手别人的项目,如何快速跑起来?
  4. 故障排查:遇到环境 Bug(如配置冲突)如何系统性定位?

一、如何管理多版本Python? #

很多混乱源于搞不清工具的职责。我们先理清 pyenv、pip、poetry 和 uv 的关系:

  1. Python 版本管理:pyenv 解决的问题:Ubuntu 22.04 自带 Python 3.10,但你想用 Python 3.12,或者不同项目需要不同版本。 原则:永远不要污染/修改系统的 /usr/bin/python3。 方案:使用 pyenv 在用户目录下安装多个隔离的 Python 版本。

推荐工具:pyenv

  1. 安装pyenv

    curl https://pyenv.run | bash
    # 在~/.bashrc或~/.zshrc中添加:
    # export PYENV_ROOT="$HOME/.pyenv"
    # export PATH="$PYENV_ROOT/bin:$PATH"
    # eval "$(pyenv init -)"
    
  2. 安装特定Python版本

    pyenv install 3.12.0      # 安装Python 3.12
    pyenv install 3.11.5      # 安装Python 3.11
    pyenv versions            # 查看已安装版本
    
  3. 版本切换

    pyenv global 3.12.0       # 设置全局默认版本
    pyenv local 3.11.5        # 设置当前目录版本(创建.python-version文件)
    
  4. ** 避免的做法**

    • 不要从源码编译安装到/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-commitpip 安装包时,报错: ERROR: Cannot set --home and --prefix together

这是环境管理中非常经典的一个错误。下面我们复盘整个排查过程,学习排查思路。

1. 排查思路 (SOP) #

遇到环境问题,按以下顺序检查:

  1. 读报错:分析互斥参数。
  2. 查环境env | grep PYTHON
  3. 查配置pip config list (最常被忽略的一步)。
  4. 查路径which pythonsys.path

2. 详细排查过程 #

第一阶段:分析报错 #

错误信息 Cannot set --home and --prefix together 说明 pip 在执行时,接收到了两个冲突的指令:

  • --home:指定安装到用户目录(pre-commit 内部常用)。
  • --prefixtarget:指定安装到特定前缀。 结论:必然有一个参数是隐式生效的(比如通过全局配置文件)。

第二阶段:检查环境变量 #

执行 env | grep -E "PYTHON|HOME|PREFIX"

PYTHON_HOME=/usr/local
PYTHONPATH=/usr/local/lib/python3.12/site-packages
  • 分析:这里发现了坏味道。PYTHON_HOMEPYTHONPATH 最好不要在全局(.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 的全局配置应尽可能保持纯净。

  1. 定位文件
    find ~/.config/pip ~/.pip /etc/pip* -name "pip.conf"
    # 结果:/home/narwal/.config/pip/pip.conf
    
  2. 移除冲突配置: 删除 target 行,仅保留镜像源配置。
    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple
    # target = ...  <-- 删除这行
    
  3. 清理缓存
    rm -rf ~/.cache/pre-commit
    

四、 避坑指南:环境配置红线 #

为了避免未来再踩坑,请遵守以下 “红线”:

  1. 禁止设置全局 targetprefix: 永远不要在 pip.conf 中设置这两个参数,它们会破坏虚拟环境的隔离性。
  2. 慎用全局 PYTHONPATH: 不要在 .bashrcexport PYTHONPATH=...。如果项目需要路径,请在项目级 .env 文件或 IDE 配置中设置。
  3. 不要用 sudo pip: 这会通过系统 Python 安装包,可能搞挂 Ubuntu 的系统工具(如 apt)。
  4. 始终使用虚拟环境: 无论是 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 隔离依赖,保持全局配置的纯净,大部分问题都能迎刃而解。