为什么你的代码在别人电脑上跑不起来?一个Python依赖的鬼故事
昨晚加班到凌晨2点,同事小明兴冲冲跑过来:”帮我跑一下这个脚本,本地测了一天了,绝对稳!”
我接过脚本,python3 main.py,屏幕上蹦出三行大红字——ModuleNotFoundError: No module named 'pandas'。
小明愣了三秒:”啊?我装了的啊。”
这个故事每个程序员都经历过。今天不聊高大上的架构设计,聊一个让所有人头皮发麻的话题:Python依赖管理。
第一层地狱:pip install跑了一天,结果同事说”我用的Python 2″
Python最经典的陷阱:同一台机器上装了3个Python版本。你自己pip install装到了Python 3.10,同事的系统默认用3.8。两个版本各玩各的,你装你的,它缺它的。
解决方案:永远、永远、永远在虚拟环境里干活。
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
这三行命令,能解决你人生中50%的Python Bug。
第二层地狱:requirements.txt写了个寂寞
很多人的requirements.txt长这样:
pandas
numpy
requests
flask
朋友,这不叫依赖管理,这叫摆烂。你同事拿到你这个文件,鬼知道该装哪个版本。下周他pip一更新,pandas从1.0升到2.0,一堆API不兼容,你的代码直接罢工。
正确姿势:冻结版本号。
pip freeze > requirements.txt
出来的版本长这样:
pandas==2.1.4
numpy==1.26.2
requests==2.31.0
flask==3.0.0
版本锁死,天下太平。下次升级是你自己想升的时候,不是pip擅自升级的时候。
第三层地狱:系统依赖装到一半,生产环境炸了
跑Python没事,但装psycopg2需要libpq-dev,装Pillow需要libjpeg。你在Mac上brew install一把梭,上了Linux服务器——”Package not found”。你开始在服务器上apt-get、yum、甚至手动编译源码,生产环境的稳定性?不存在的。
救星:Docker。
FROM python:3.11-slim
RUN apt-get update && apt-get install -y libpq-dev
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
一次构建,到处跑。你的Mac能跑,AWS能跑,客户那台破Windows服务器也能跑。
总结一下
| 问题 | 症状 | 解药 |
|---|---|---|
| 多版本混乱 | ModuleNotFoundError | 虚拟环境 |
| 版本爆炸 | 隔天跑不通 | pip freeze |
| 环境差异 | 我电脑上没问题啊 | Docker |
最讽刺的是:Python号称”开箱即用”,但Python项目的依赖管理是所有语言里最灾难的。Go编译成一个二进制文件就能扔到任何机器上跑,Node有lockfile保证版本一致性,Rust的Cargo更是把依赖管理做成了艺术品。Python呢?快40年了,还在跟pip打架。
今日作业: 打开你的任何Python项目,检查三个地方:
1. 有没有.gitignore(把venv/和__pycache__/加上)
2. requirements.txt有没有版本号(没有的话pip freeze > requirements.txt)
3. 有没有Dockerfile(没有的话,今天就是最好的开始)