pip 说装好了,Python 说没装,谁在撒谎?
新项目要部署,分到一台干净的 Ubuntu 服务器。我想着规范一点,别像以前那样 sudo pip 装到系统里搞得乱七八糟,于是认认真真建了个虚拟环境:
提示符前缀变成了 (venv),稳。接着装依赖:
终端友好地回了我一句:
我寻思齐活了,跑应用:
然后它甩给我一行红字:
我盯着这行字看了三秒。刚才不是 Successfully installed 吗?flask 去哪了?
一通乱查
我开始自信满满地排查。
- 是不是装错了名字?
pip show flask,有啊,版本、位置都列得明明白白。
- 是不是装到了别的 Python 上?我寻思不至于,明明都在
(venv)里啊。
- 是不是 Python 版本对不上?
python --version,3.10,和建 venv 时一样。
- 是不是 venv 没激活成功?看看提示符,
(venv)还在,echo $VIRTUAL_ENV也指向了 venv 目录。
- 是不是 flask 装到了 user 目录?我甚至怀疑自己手滑加了
--user。
我又开始往玄学方向怀疑:
- 是不是这台机器中邪了?
- 是不是 flask 3.0 和我的代码不兼容,import 时静默失败了?(我居然真去翻了一眼神农架级别的 flask changelog)
- 是不是 venv 的 site-packages 权限不对,装进去了却读不出来?
一个多小时过去了,pip show flask 说装好了,python -c "import flask" 说没装,两个人各执一词,我夹在中间,谁也不敢信。
真相
快下班的时候,我鬼使神差地敲了条平时压根想不起来的命令:
它回我:
不是 ~/venv/bin/pip,是系统的 pip。
再敲:
python 是 venv 的,pip 是系统的——哥俩根本不是一个家的人。
我 pip install flask,用的是系统 pip,装到了系统的 site-packages;我 python app.py,用的是 venv 的 python,去 venv 的 site-packages 里找 flask——当然找不到。
那为什么 venv 里没有 pip?因为这台 Ubuntu 上 python3-venv 这个包没装全,python3 -m venv 建出来的环境里压根没有 pip 这个可执行文件。source activate 老老实实把 venv/bin 加到了 PATH 最前面,可 venv/bin 里根本没有 pip,PATH 顺着往下找,就找到了系统的 /usr/bin/pip。提示符显示 (venv),给人一种"我在虚拟环境里"的错觉,可 pip 早就叛逃到系统去了。
解决简单到令人发指:
python -m pip 强制用当前 python 对应的 pip,管你是哪个 python,装哪算哪,绝不分家。或者老老实实 apt install python3-venv python3-pip 把 venv 补全。
跑完,flask 乖乖出现在 venv 里,应用秒起。
几条血泪教训
折腾一个多小时换来的几句话,送给每一个"觉得自己懂虚拟环境"的人:
- 激活了 venv,不代表
pip就是 venv 的。(venv)这个前缀只能证明 PATH 被改了,不能证明 venv/bin/pip 真的存在。养成习惯,激活后第一件事which pip、which python,两个都看一眼,别像我一样只信提示符。
- 永远用
python -m pip,别用裸pip。python -m pip强制 pip 跟着当前解释器走,装哪找哪,物理上杜绝"装的人和找的人不是同一个 python"。这一条能消灭虚拟环境里一半的灵异事件。
venv里没有 pip,是 Debian/Ubuntu 的老传统。 系统的python3和python3-venv、python3-pip是分开的 apt 包,少装一个,建出来的 venv 就是残废的。新机器配环境,先apt install python3-venv python3-pip打底,再建 venv,省得后面抓瞎。
pip show说的位置,未必是python找的位置。 排查 import 失败,别只看pip show,要看python -c "import sys; print(sys.path)"。前者告诉你"装哪了",后者告诉你"找哪了"——这俩对不上,就是你翻车的根。
- 点赞
- 收藏
- 关注作者
评论(0)