“在我机器上能跑”的头号原因是依赖装在了全局环境里。隔离是底线,不是可选项。
venv 与 virtualenvwrapper
| 方案 | 特点 | 适合 |
|---|---|---|
python -m venv |
标准库自带,零额外依赖 | 大多数场景(推荐) |
virtualenvwrapper |
集中存放环境、workon 切换 |
同时维护很多项目 |
conda |
连 Python 版本一起管 | 科学计算、非 Python 依赖多 |
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -U pip
pip install -r requirements.txt
deactivate
三条纪律
.venv/提交进仓库 —— 绝对不要。体积大、平台相关、还会让“干净安装”掩盖缺失的依赖声明。写进.gitignore。- 依赖必须有声明文件 ——
requirements.txt或pyproject.toml。只靠pip freeze得到的列表会把间接依赖也钉死,升级时很难受。 - 生产环境用锁定版本 —— 部署时
pip install -r requirements.lock(或pip install --no-deps -r),保证与测试环境一致。
常见报错对照
| 报错 | 含义 | 处置 |
|---|---|---|
ModuleNotFoundError(但已 install) |
装到了另一个解释器/环境 | which python、which pip 确认是同一个 |
pip: command not found |
用了系统 pip 且未激活环境 | 用 python -m pip 更稳 |
| 权限错误 | 试图装到系统目录 | 激活虚拟环境,别用 sudo pip |
| 中文/编码报错 | 系统 locale 不完整 | 装 locales 或设 PYTHONUTF8=1 |
部署时的最小可复现流程
git pull
python3 -m venv .venv --clear # 每次都重建,避免残留
.venv/bin/pip install -U pip
.venv/bin/pip install -r requirements.lock
systemctl restart my-service
用绝对路径调用解释器(.venv/bin/python)而不是依赖 activate:systemd、cron、CI 里没有交互式 shell,“忘了 activate”是高频事故。
与 Node 生态的对照:
venv≈node_modules(项目级隔离),requirements.lock≈pnpm-lock.yaml(可复现安装)。区别在于 Node 默认就是项目级隔离,而 Python 需要你主动创建。
