当 `venv` 撒谎时:在 Ubuntu 上调试幽灵 Python 3.4
Source: Dev.to
背景
虚拟环境本应隔离你的项目。
当 venv 静默地使用了一个古老的 Python 解释器时,一切都可能出错。
症状
python3 -m venv venv
source venv/bin/activate
- venv 中缺少
pip ensurepip因 SSL 错误而失败get-pip.py拒绝运行pip freeze什么也不显示- 导入
ssl失败
关键线索:
python3 --version
# Python 3.4.10
然而 Ubuntu 报告:
sudo apt install python3
# python3 is already the newest version (3.12.3)
诊断
PATH 优先级
Linux 使用 $PATH 来解析可执行文件。典型顺序:
/usr/local/bin
/usr/bin
如果手动编译并安装了旧的 Python 到:
/usr/local/bin/python3
/usr/local/lib/python3.4
它会遮蔽系统管理的 Python(位于 /usr/bin/python3)。
执行:
python3 -m venv venv
因此会使用 Python 3.4 创建虚拟环境,而不是 3.12。
Python 3.4 已于 2019 年停止维护,缺少现代 SSL 支持,无法运行当前的 pip,并且与今天的工具链不兼容。
检查正在使用的解释器:
which python3
# /usr/local/bin/python3 ← 问题所在
正确的系统解释器应为:
which python3
# /usr/bin/python3
如果两者不同,说明系统中存在多个安装。
测试 SSL 支持:
python3 -c "import ssl"
# ImportError: No module named '_ssl'
在 venv 中:
python --version
which python
which pip
如果版本显示 3.4.x,说明虚拟环境是用错误的解释器创建的。
为什么 venv 没能保护你
venv 只会克隆创建它时使用的解释器:
pythonX -m venv venv
如果 pythonX 指向的是过时的二进制文件,生成的环境就会继承这些问题。所谓“垃圾进 → 垃圾出”。
解决方案
-
移除过时的解释器
sudo rm /usr/local/bin/python3 sudo rm /usr/local/bin/python sudo rm -rf /usr/local/lib/python3.4 hash -r # 清除命令哈希缓存 -
验证系统 Python
which python3 # /usr/bin/python3 python3 --version # Python 3.12.3 -
使用正确的解释器重新创建虚拟环境
/usr/bin/python3 -m venv venv source venv/bin/activate -
确认环境
python --version # Python 3.12.3 which python # .../venv/bin/python which pip # .../venv/bin/pip
现在 ssl 正常工作,pip 能安装包,环境也可复现。
教训
问题之所以隐蔽,是因为系统表面上正常,直到你遇到 SSL、pip 或依赖错误时才显现。调试 Linux 上的 Python 环境时:
- 在指责
pip、venv或 Ubuntu 之前,务必先确认解释器路径(which python3、python3 --version)。 - 大多数环境问题其实都是 PATH 引起的伪装。