FAQ-16:在 Ubuntu 上安装 Python 3

预计阅读时间:15 分钟

📖 目录

问题速查表

问题解决章节
安装系统自带 Python 版本方式一:使用 APT 官方仓库(最安全)
需要安装其他 Python 版本方式二:使用 deadsnakes PPA 安装其他版本
需要定制编译选项方式三:从源码编译(最灵活)
pip install 报 externally-managed-environment 错误错误一:pip install 报 externally-managed-environment 错误
python3 命令找不到错误二:python3 命令找不到
pip 安装速度慢或超时错误三:pip 安装速度慢或超时
虚拟环境创建失败(ensurepip 缺失)错误四:虚拟环境创建失败——ModuleNotFoundError: No module named 'ensurepip'

Python 是 Linux 运维和开发的必备语言。系统管理脚本、数据分析、自动化工具、Web 开发、机器学习等几乎所有领域都有 Python 的身影。Ubuntu 通常已预装 Python 3,但版本可能不是最新的,且缺少 pip 和 venv 等常用组件。本文介绍多种安装方式,帮助你根据实际需求选择最合适的方案。

安装方法

方式一:使用 APT 官方仓库(最安全)

Ubuntu 官方仓库的 Python 版本经过充分测试,与系统兼容性最好,适合大多数用户。

# 更新包索引
sudo apt update

# 安装 Python 3 及常用工具
sudo apt install -y python3 python3-pip python3-venv

# 验证安装
python3 --version
pip3 --version

Ubuntu 22.04 预装 Python 3.10,24.04 预装 Python 3.12。如果你对版本没有特殊要求,直接使用系统自带版本即可。

方式二:使用 deadsnakes PPA 安装其他版本

deadsnakes 是最流行的第三方 Python PPA,提供几乎所有 Python 版本的预编译包。

# 添加 deadsnakes PPA
sudo apt install -y software-properties-common
sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo apt update

# 安装 Python 3.11 或 3.12 等版本
sudo apt install -y python3.11 python3.11-pip python3.11-venv
sudo apt install -y python3.12 python3.12-pip python3.12-venv

# 使用特定版本
python3.11 --version
python3.12 --version

# 设为系统默认(可选,谨慎操作)
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
sudo update-alternatives --config python3

方式三:从源码编译(最灵活)

当你需要启用特定编译选项、调试构建,或者官方仓库/PPA 都没有你需要的版本时,可以选择源码编译。

# 安装编译依赖
sudo apt install -y build-essential libssl-dev zlib1g-dev \
  libncurses5-dev libreadline-dev libsqlite3-dev \
  libgdbm-dev libbz2-dev libffi-dev liblzma-dev

# 下载并编译
wget https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tar.xz
tar -xf Python-3.12.4.tar.xz
cd Python-3.12.4

# 配置(--enable-optimizations 会运行测试套件优化编译,耗时较长但性能更好)
./configure --enable-optimizations

# 编译(-j 参数指定并行编译数,通常等于 CPU 核心数)
make -j$(nproc)

# 安装(altinstall 不会覆盖系统默认的 python3)
sudo make altinstall

# 验证
python3.12 --version

注意:使用 make altinstall 而非 make install,前者会安装为 python3.x 而非覆盖系统的 python3,避免破坏系统依赖。

版本管理

当你通过不同方式安装了多个 Python 版本后,可以通过以下方式管理和切换:

# 查看系统上所有已安装的 Python 版本
ls /usr/bin/python3*

# 使用 update-alternatives 管理默认版本
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 3

# 交互式选择默认版本
sudo update-alternatives --config python3

# 使用 pyenv 管理多版本(更灵活的方案)
curl https://pyenv.run | bash

# 将以下内容添加到 ~/.bashrc
# export PATH="$HOME/.pyenv/bin:$PATH"
# eval "$(pyenv init -)"
# eval "$(pyenv virtualenv-init -)"

# 使用 pyenv 安装和切换版本
pyenv install 3.12.4
pyenv global 3.12.4
pyenv local 3.11.9

deadsnakes PPA 使用细节:PPA 名源于旧 Python 名称 "dead snakes"(已停止维护的版本)。安装后建议优先用 python3.x 完整版本号调用(如 python3.12),不要动 /usr/bin/python3 符号链接——Ubuntu 系统组件(apt、gnome 等)依赖它指向特定版本,篡改会导致系统损坏。

虚拟环境实战

虚拟环境是 Python 项目依赖隔离的标准做法,避免全局污染与版本冲突。

# 创建虚拟环境(Python 3.8+ 内置 venv)
python3 -m venv ~/projects/myapp/.venv

# 激活(每次进入项目后执行)
source ~/projects/myapp/.venv/bin/activate

# 激活后 pip 与 python 都指向虚拟环境
which python   # ~/projects/myapp/.venv/bin/python
pip --version  # 版本号末尾带 (myapp/.venv)

# 安装依赖并导出锁文件
pip install flask requests
pip freeze > requirements.txt

# 退出虚拟环境
deactivate

# 在新机器/CI 中一键还原
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

venv vs conda vs virtualenv 选型:Python 3.8+ 内置 venv 足够 90% 场景(轻量、无需额外安装);conda 适合科学计算(可管非 Python 依赖如 CUDA);virtualenv 是 venv 前身,仅遗留项目使用。团队协作建议把 requirements.txt(或 poetry/pipenv 锁文件)提交到 Git,并加 .venv/.gitignore

常见错误

错误一:pip install 报 externally-managed-environment 错误

Ubuntu 23.04+ 引入了 PEP 668,限制了 pip 直接安装到系统 Python 的行为。解决方法是使用虚拟环境:

# 方法一:创建虚拟环境(推荐)
python3 -m venv ~/myenv
source ~/myenv/bin/activate
pip install requests flask

# 方法二:强制安装(不推荐,可能破坏系统)
pip install --break-system-packages requests

错误二:python3 命令找不到

某些极简安装的 Ubuntu 系统可能没有预装 Python3:

# 安装 Python3
sudo apt update
sudo apt install -y python3

# 如果需要让 python 命令指向 python3
sudo apt install -y python-is-python3

错误三:pip 安装速度慢或超时

国内网络环境下,使用镜像源可以显著加速:

# 临时使用清华镜像
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

# 永久配置
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << 'EOF'
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
EOF

错误四:虚拟环境创建失败——ModuleNotFoundError: No module named 'ensurepip'

部分 Ubuntu 版本默认没有安装 venv 模块:

# 安装 venv 模块
sudo apt install -y python3-venv

# 然后重新创建虚拟环境
python3 -m venv ~/myenv

真实案例

案例 A:误删 /usr/bin/python3 符号链接导致 apt 全面报错

用户为了"升级 Python"执行了 sudo rm /usr/bin/python3 并替换为其他版本软链,随后 apt 报出大量依赖错误,系统软件无法更新。

# apt 报错样例
E: /usr/bin/python3: No such file or directory
Traceback (most recent call last):
  File "/usr/lib/cnf/update.py", line 3, in <module>
    import apt
ModuleNotFoundError: No module named 'apt'

# 排查:apt 依赖系统 python3
ls -la /usr/bin/python3*   # 软链已被破坏

# 修复:恢复官方 python3 包(在救援环境或直接重装)
sudo apt-get install --reinstall python3-minimal python3-apt

# 验证
python3 --version         # 恢复为系统版本
sudo apt update           # 报错消失

根因:篡改了系统关键符号链接;教训:永远不要动 /usr/bin/python3,多版本共存用 python3.12 全名或 pyenv/update-alternatives。

案例 B:pip install 报 externally-managed-environment

# Ubuntu 23.04+ 的系统 Python 报错
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, ...

# 正确解法:创建虚拟环境(推荐)
python3 -m venv .venv
source .venv/bin/activate
pip install requests      # 正常

# 只在确认需要时使用 --break-system-packages(不推荐)
# pip install --break-system-packages requests

根因:PEP 668 保护系统 Python 不被 pip 污染;验证pip show requests 显示安装在 .venv 路径下,deactivate 后系统 pip 不受影响。

案例 C:Python 3.12 移除 distutils 导致旧脚本报错

现象:升级到 Python 3.12 后,某些使用 distutils 的脚本报 ModuleNotFoundError: No module named 'distutils'

# Python 3.12 移除了 distutils(PEP 632)
$ python3 -c "import distutils"
ModuleNotFoundError: No module named 'distutils'

# 解决方案:安装 setuptools(包含 distutils 的替代实现)
pip install setuptools

# 或修改脚本,用 importlib 替代 distutils
# 旧:from distutils.core import setup
# 新:from setuptools import setup

根因:Python 3.12 移除了 distutils 模块(PEP 632),推荐使用 setuptools 替代。

修复:安装 setuptools,或将脚本中的 distutils 引用改为 setuptools

验证安装

# 检查版本
python3 --version
pip3 --version

# 测试导入标准库
python3 -c "import ssl, sqlite3, json; print('标准库模块加载正常')"

# 测试虚拟环境
python3 -m venv /tmp/test-venv
source /tmp/test-venv/bin/activate
pip install requests
python3 -c "import requests; print('requests', requests.__version__)"
deactivate

# 清理测试环境
rm -rf /tmp/test-venv

案例 D:pip install 报 Could not find a version that satisfies the requirement

用户安装 numpy 时遇到找不到满足要求的版本错误,但该包明明存在。

# 报错
ERROR: Could not find a version that satisfies the requirement numpy
ERROR: No matching distribution found for numpy

# 排查:检查 Python 版本
python3 --version    # Python 3.6.9(Ubuntu 18.04 自带)
# numpy 1.24+ 已放弃对 Python 3.6 的支持

# 修复方案一:升级 Python 版本(推荐)
sudo add-apt-repository -y ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.12 python3.12-pip python3.12-venv
python3.12 -m venv ~/myenv
source ~/myenv/bin/activate
pip install numpy    # 成功

# 修复方案二:安装旧版 numpy(不推荐,功能受限)
pip install "numpy<1.24"

# 验证
python3 -c "import numpy; print(numpy.__version__)"

根因:新版库逐步放弃对旧 Python 版本的支持;修复:升级 Python 到受支持版本;预防:新项目至少使用 Python 3.10+,避免使用已停止维护的 Python 3.6/3.7。

案例 E:venv 创建成功但 activate 后 which python 指向系统版本

用户创建虚拟环境并激活后,which python 仍然指向 /usr/bin/python3,pip 安装的包到了系统目录。

# 现象
python3 -m venv ~/myenv
source ~/myenv/bin/activate
which python       # /usr/bin/python3(应为 ~/myenv/bin/python)

# 排查:检查 activate 脚本
head -5 ~/myenv/bin/activate
# 缺少 VIRTUAL_ENV 变量或 PATH 未正确设置

# 原因:venv 是用系统包管理器安装的,可能不完整
dpkg -l | grep python3-venv

# 修复:重新安装 venv 模块
sudo apt install -y --reinstall python3.12-venv

# 重建虚拟环境
rm -rf ~/myenv
python3.12 -m venv ~/myenv
source ~/myenv/bin/activate
which python       # ~/myenv/bin/python(正确)

# 验证
pip install requests
which pip          # ~/myenv/bin/pip

根因python3-venv 包不完整或版本不匹配,导致 activate 脚本未正确设置环境变量;修复:重装 python3-venv 包并重建虚拟环境。

版本管理详解

pyenv 完整使用指南

pyenv 是最流行的 Python 多版本管理工具,支持编译安装多个版本并一键切换:

# 安装 pyenv 依赖
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
  libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
  libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
  libffi-dev liblzma-dev

# 安装 pyenv
curl https://pyenv.run | bash

# 配置 shell 初始化(~/.bashrc 末尾)
cat >> ~/.bashrc << 'EOF'
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
EOF
source ~/.bashrc

# 查看可安装版本
pyenv install --list | grep "3.12"
# 3.12.0
# 3.12.1
# 3.12.4

# 安装指定版本(编译安装,需要时间)
pyenv install 3.12.4

# 设置全局默认版本
pyenv global 3.12.4

# 设置项目本地版本(在项目目录下执行)
cd ~/myproject
pyenv local 3.11.9
# 会生成 .python-version 文件

# 查看已安装版本
pyenv versions
# * system(当前)
#   3.11.9
#   3.12.4

# 卸载版本
pyenv uninstall 3.11.9

# 使用 pyenv-virtualenv 创建虚拟环境
pyenv virtualenv 3.12.4 myenv
pyenv activate myenv
pip install flask

# 退出虚拟环境
pyenv deactivate

pyenv vs venv vs conda 选型决策

# 场景一:简单项目,单版本 Python
# → 系统自带 Python + venv(最简单)
python3 -m venv .venv
source .venv/bin/activate

# 场景二:多项目需要不同 Python 版本
# → pyenv + venv
pyenv install 3.11.9 3.12.4
cd project-a && pyenv local 3.11.9
cd project-b && pyenv local 3.12.4

# 场景三:科学计算,需要 CUDA/cuDNN 等非 Python 依赖
# → conda
conda create -n myenv python=3.12
conda activate myenv
conda install numpy pytorch

# 场景四:生产环境 Docker 部署
# → 系统 Python + venv(镜像最小)
FROM python:3.12-slim
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install -r requirements.txt

update-alternatives 精细管理

# 安装多个版本后注册
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 2
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 3

# 查看当前状态
sudo update-alternatives --display python3

# 交互式选择
sudo update-alternatives --config python3
# 选择编号即可切换

# 脚本中自动选择(非交互式)
sudo update-alternatives --set python3 /usr/bin/python3.12

# 恢复默认
sudo update-alternatives --auto python3

# 注意:Ubuntu 的 apt 依赖特定的 python3 版本
# 改了默认版本后,可能需要重新链接 apt 的 Python 依赖
# 通常不建议用 update-alternatives 改系统默认 python3

故障排查决策树

当 Python 环境出现问题时,按以下流程排查:

问题:python3 或 pip3 命令找不到
├── which python3 有输出?
│   ├── 是 → PATH 正常,检查别名:alias | grep python
│   └── 否 → 查找安装位置:
│       ├── ls /usr/bin/python3* 2>/dev/null
│       │   ├── 有 → 加入 PATH
│       │   └── 无 → 未安装:sudo apt install -y python3 python3-pip
│       └── pyenv 环境?
│           ├── pyenv versions 查看已安装版本
│           ├── pyenv global  激活
│           └── source ~/.bashrc 重新加载 pyenv 初始化

问题:pip install 报 externally-managed-environment
├── 检查 /usr/lib/python3.x/EXTERNALLY-MANAGED 文件是否存在
│   ├── 存在 → 使用虚拟环境:python3 -m venv .venv
│   └── 不存在 → PEP 668 未启用,可直接 pip install
└── 强制安装(不推荐):pip install --break-system-packages

问题:pip install 报 Could not find a version
├── 检查 Python 版本:python3 --version
│   ├── Python < 3.8 → 升级 Python(deadsnakes PPA 或 pyenv)
│   └── Python >= 3.8 → 继续排查
├── 检查 pip 版本:pip --version
│   ├── pip 过旧 → pip install --upgrade pip
│   └── pip 正常 → 检查网络:curl -I https://pypi.org
├── 检查平台兼容性:pip install  --only-binary=:all:
│   ├── 不兼容 → 该包没有预编译轮子,需要编译依赖
│   └── 兼容 → 检查是否指定了错误的 index-url
└── 尝试指定版本:pip install ==

问题:ModuleNotFoundError: No module named 'xxx'
├── 检查是否在虚拟环境中:which python
│   ├── 在虚拟环境 → 检查虚拟环境是否安装了该包:pip list | grep xxx
│   ├── 不在 → 检查系统是否安装:pip3 list | grep xxx
│   └── 都没有 → 安装:pip install xxx
├── 检查 Python 版本兼容性
│   └── 某些包只支持特定 Python 版本
└── 检查包名拼写(PyPI 包名可能与 import 名不同)

问题:虚拟环境创建失败
├── ModuleNotFoundError: No module named 'ensurepip'
│   └── sudo apt install -y python3-venv
├── ModuleNotFoundError: No module named 'distutils'
│   └── sudo apt install -y python3-distutils 或 pip install setuptools
└── 权限错误
    └── 不要用 sudo 创建虚拟环境,用用户权限

问题:pip install 速度慢
├── 配置国内镜像源(清华/阿里云/中科大)
├── 使用 --timeout 参数增大超时:pip install --timeout 60 xxx
├── 使用并行下载:pip install --use-feature=fast-deps xxx
└── 预下载后离线安装:pip download -d ./pkgs xxx && pip install --no-index --find-links=./pkgs xxx

生产环境配置建议

  • 使用 pyproject.toml 管理项目元数据:PEP 621 定义了 pyproject.toml 标准,替代 setup.pysetup.cfg。新项目推荐使用 pyproject.toml 声明依赖和构建配置。
  • 使用 poetry 或 pip-tools 锁定依赖requirements.txt 不锁定间接依赖版本,可能导致环境不一致。推荐使用 poetry(生成 poetry.lock)或 pip-compile(生成 requirements.txt 带精确版本)。
  • Docker 中使用多阶段构建:builder 阶段安装编译依赖,runtime 阶段只复制虚拟环境,减小镜像体积。
  • 设置 PIP_NO_CACHE_DIR=1:CI/Docker 构建中禁用 pip 缓存,避免缓存占用空间。
  • 使用预编译轮子pip install --only-binary=:all: -r requirements.txt 可避免编译原生模块,加速安装。
  • 定期安全扫描pip install safety && safety check -r requirements.txt 检查已知漏洞,CI 中加入安全卡点。
  • 使用 uv 替代 pip:uv 是 Rust 编写的超快 Python 包管理器,安装速度比 pip 快 10-100 倍,兼容 requirements.txt 格式。

案例 F:Python 虚拟环境中 pip 安装报错 "externally-managed-environment" 但系统 Python 正常

用户在虚拟环境中执行 pip install 仍报 PEP 668 错误,但虚拟环境应该是隔离的。

# 现象
source ~/myenv/bin/activate
pip install requests
# error: externally-managed-environment

# 排查:检查虚拟环境是否真的隔离
which python    # ~/myenv/bin/python(正确)
which pip       # /usr/bin/pip3(错误!没有使用虚拟环境的 pip)

# 原因:虚拟环境不完整,缺少 pip 的软链接
ls ~/myenv/bin/pip*
# 无输出

# 修复:在虚拟环境中重新安装 pip
~/myenv/bin/python -m ensurepip
~/myenv/bin/python -m pip install --upgrade pip

# 或重建虚拟环境
rm -rf ~/myenv
python3 -m venv ~/myenv --without-pip
source ~/myenv/bin/activate
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
rm get-pip.py

# 验证
which pip       # ~/myenv/bin/pip
pip install requests   # 成功

根因:虚拟环境创建时未正确包含 pip(可能 venv 模块不完整),导致 pip 命令指向系统 pip;修复:在虚拟环境中重新安装 pip 或重建虚拟环境。

案例 G:pyenv install 报 "configure: error: C compiler cannot create executables"

使用 pyenv 安装 Python 时遇到 C 编译器错误。

# 报错
WARNING: The Python readline extension was not compiled. Missing the GNU readline lib?
configure: error: C compiler cannot create executables

# 排查:缺少编译依赖
apt list --installed 2>/dev/null | grep build-essential

# 修复:安装编译工具链和开发库
sudo apt install -y build-essential libssl-dev zlib1g-dev \
  libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
  libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
  libffi-dev liblzma-dev

# 重试安装
pyenv install 3.12.4

# 如果仍然失败,尝试设置编译选项
PYTHON_CONFIGURE_OPTS="--enable-optimizations" pyenv install 3.12.4

根因:pyenv 使用源码编译安装 Python,缺少必要的 C 编译依赖;修复:安装 build-essential 及相关开发库。

案例 H:pip freeze 导出的 requirements.txt 包含不需要的包

pip freeze 导出了所有包(包括依赖的依赖),导致 requirements.txt 冗长且难以维护。

# 现象
pip freeze > requirements.txt
# 文件包含 200+ 行,包括 setuptools、pip 本身等

# 问题:setuptools 和 pip 本身不应出现在 requirements.txt
# 它们是构建工具,不是项目依赖

# 修复:过滤不需要的包
pip freeze | grep -v "^\(setuptools\|pip\|wheel\)" > requirements.txt

# 更好的方案:使用 pip-chill 或 pipreqs
pip install pip-chill
pip-chill > requirements.txt    # 只导出直接依赖

# 或使用 pipreqs(按实际 import 导出)
pip install pipreqs
pipreqs . --force    # 扫描项目中的 import 语句

# 使用 poetry 管理(最佳方案)
poetry export -f requirements.txt --output requirements.txt

根因pip freeze 导出所有已安装的包,包括间接依赖和构建工具,导致 requirements.txt 膨胀;修复:使用 pip-chillpipreqspoetry 导出更干净的依赖列表。

最佳实践

  • 始终使用虚拟环境:每个项目创建独立的 venv,避免包版本冲突,也方便依赖管理和迁移。
  • 优先使用系统自带版本:除非项目有明确的版本要求,否则使用 Ubuntu 预装的 Python 版本最省心。
  • 用 pip freeze 导出依赖:项目完成时运行 pip freeze > requirements.txt,方便在其他机器复现环境。
  • 不要用 sudo pip install:这会污染系统 Python 环境,可能导致系统工具出问题。始终在虚拟环境中安装第三方包。
  • 关注 Python 版本生命周期:Python 3.8 已于 2024 年 10 月停止支持,新项目应至少使用 Python 3.10+。

延伸阅读

案例 I:pip 安装报 "ModuleNotFoundError: No module named 'distutils'"

现象:在 Python 3.12 环境中执行 pip install 报错:

$ pip install numpy
error: subprocess-exited-with-error

  × Building wheel for numpy did not run successfully.
  │ exit code: 1
  ...
  ModuleNotFoundError: No module named 'distutils'

根因:Python 3.12 移除了 distutils 模块(PEP 632),某些依赖 distutils 的包在构建时会失败。

修复

# 安装 setuptools(包含 distutils 替代实现)
pip install setuptools

# 重新安装
pip install numpy

# 或直接安装预编译轮子(避免构建)
pip install --only-binary=:all: numpy

预防:Python 3.12+ 环境中确保 setuptools 已安装。优先使用预编译轮子(--only-binary=:all:)避免构建问题。

↑ 回到顶部