Python 虚拟环境与依赖锁定:六个常见坑

举报
yd_284037603 发表于 2026/11/08 10:34:35 2026/11/08
【摘要】 把 Python 依赖管理里最容易踩的六个坑讲清楚:虚拟环境没激活、不锁版本、pip freeze 倒出整棵依赖树、.venv 被提交、sudo pip 污染系统 Python、镜像源与缓存不一致,附可直接复制的命令和一条可复现的落地流程。

先说在前面

「在我机器上跑得好好的」十次里有八次是依赖问题:Python 版本不同、包装在全局环境、requirements.txt 没锁版本、或者某个包只在 Windows 上装得到。这些问题不会在写代码时暴露,往往在 CI、部署或换同事接手时才炸。下面六个按出现频率排,每条给一条能立刻验证的命令。

1. 忘了激活虚拟环境,包装到了全局

最常见的开头:pip install requests 装进了系统 Python,脚本却用另一个解释器跑,于是 ModuleNotFoundError 和「明明装过了」同时出现。先确认当前到底在用哪个 Python、哪个 pip:

which python3; python3 -c "import sys; print(sys.executable)"
python3 -m pip --version
# 更稳的习惯:永远用解释器带 pip
python3 -m pip install requests

python3 -m venv .venv 建好环境后要 source .venv/bin/activate(Windows 是 .venv\Scripts\activate)。IDE 里还要注意解释器路径有没有指向 .venv,终端激活了但 IDE 没切,照样会踩坑。

2. requirements.txt 只写包名,不锁版本

手写 requests、pandas 而不带版本号,等于把构建结果交给「安装当天 PyPI 上是什么版本」。上游一发不兼容更新,CI 就红,而且本地复现不出来。

# 最低限度:写精确版本
requests==2.32.3
pandas==2.2.3
# 更规范:交给工具生成锁文件
pip install pip-tools
pip-compile requirements.in -o requirements.txt
pip-sync requirements.txt

requirements.in 只放直接依赖(人维护),requirements.txt 由 pip-compile 生成(机器维护,含完整传递依赖和精确版本)。别手改生成的文件。

3. 直接 pip freeze 把整棵树倒出来

pip freeze > requirements.txt 好用但有三个副作用:把传递依赖和直接依赖混在一起、带上本地才有的包(比如某个调试工具)、把平台专属包(pywin32、nvidia-*)一起写进去,换到 Linux 就装不上。

# 平台标记写法,让依赖只在对应环境生效
pywin32==306; sys_platform == "win32"
# 删除不在锁文件里的包,保证环境和锁文件一致
pip-sync requirements.txt

另外 pip freeze 会记录本地可编辑安装(-e .)的路径,别把这种绝对路径提交到仓库。

4. .venv 和 pycache 被提交进仓库

虚拟环境目录几千个文件,一旦进 Git 就很难清干净,还会把某个同事机器上的绝对路径带进历史。新建项目第一件事就是写 .gitignore:

.venv/
venv/
__pycache__/
*.py[cod]
.pytest_cache/
*.egg-info/
.env

已经提交过的目录,加忽略规则是没用的(.gitignore 只作用于未跟踪文件),要 git rm -r --cached .venv 再提交一次。

5. 用 sudo pip 或污染系统 Python

Linux 上 sudo pip install 会把包写进发行版自带的 Python,可能覆盖系统工具依赖的包,甚至把 pip 自己搞坏。macOS/Homebrew 的 Python 还有 externally-managed-environment 保护,直接装会报 error: externally-managed-environment。

# 不要 sudo pip install
python3 -m venv .venv && source .venv/bin/activate
python -m pip install -U pip
# 命令行工具用隔离安装
pipx install black

系统 Python 只用来跑系统脚本,业务依赖一律放虚拟环境;命令行小工具交给 pipx,互不干扰。

6. 镜像源与私有源混用、缓存没清

团队里有人配了公司镜像、有人用默认 PyPI,同一个锁文件可能装出不同的包(尤其是内部包和同名包)。CI 里还要留意缓存目录没随锁文件更新,导致「改了版本却还在用旧 wheel」。

pip config list
pip cache dir; pip cache purge
pip install --no-cache-dir -r requirements.txt
# CI 里让缓存键包含锁文件哈希
# key: pip-${{ hashFiles('requirements.txt') }}

建议在项目里放一份 pip.conf 或在 CI 显式指定 --index-url,把源固定下来,别依赖每个开发者的本机配置。

小结:一条能直接照抄的流程

python3 -m venv .venv → 激活并确认 sys.executable → 写 .gitignore → 只把直接依赖写进 requirements.in → pip-compile 生成锁文件 → pip-sync 安装 → CI 用同一份锁文件 + 固定镜像源 + 带哈希的缓存键。现在也可以用 uv 把这几步压到两条命令(uv venv、uv pip sync),但背后要解决的还是这六件事。把「环境是可重建的」当成默认前提,绝大多数「在我机器上是好的」就消失了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。