根本原因是pip执行PEP 517多阶段构建:解压源码→调用gcc/cl.exe编译→链接Fortran目标文件→ABI检查,每步在内存中堆积临时对象,低内存环境易触发MemoryError或OSError [Errno 12]。

根本原因不是网络慢或磁盘满,而是 pip 在本地启动了多阶段构建流程:先解压源码、再调用 C/C++ 编译器(如 gcc 或 cl.exe)、接着链接 Fortran 目标文件、最后做 ABI 兼容性检查——每一步都在内存中堆积临时对象,尤其在 Windows 或低内存机器上极易触发 MemoryError 或 OSError: [Errno 12] Cannot allocate memory。
为什么 pip install scipy 会卡在 “Building wheel for scipy”
这不是假死,是 PEP 517 构建系统正在并行编译大量 Fortran 和 C 模块(如 BLAS 接口、优化器子程序),而旧版 pip(python.exe 或 gfortran.exe 进程持续占满 CPU 和虚拟内存。
- Linux/macOS 下可加
pip install --verbose scipy 2>&1 | grep -i "compiling\|building"确认是否真在干活 - Windows 用户若看到
python.exe状态为 “挂起” 或 CPU 骤降至 0%,大概率是杀毒软件(如 360、McAfee)拦截了cl.exe子进程 - 别信“等一等就好”——若 10 分钟无日志输出、CPU
--only-binary 能绕过编译但有前提条件
强制使用预编译 wheel 是最有效解法,但必须满足三个条件,否则 pip 会悄悄回退到源码编译:
- 本地
pip版本 ≥ 23.0(pip install -U pip升级) - 目标包的 wheel 在 PyPI 上存在且匹配当前平台和 Python ABI(比如
scipy-1.13.0-cp311-cp311-win_amd64.whl) - 没混用 conda 和 pip 安装的依赖——例如
numpy若是 conda 装的,pip 装scipy时可能因 ABI 不一致触发重编译
执行命令:pip install --only-binary=scipy scipy;若失败,立刻补上:pip install -U pip setuptools wheel 再重试。
Windows 用户优先走 conda,不是因为 pip 不行,而是链接器更稳
Windows 上 link.exe 在解析几十个 .obj 文件时会 mmap 大量虚拟内存,操作系统用 swap 撑住,表现为磁盘狂闪、VIRT 内存涨到 20GB+、但 RSS 不动——这其实是链接阶段的正常行为,但容易被误判为 OOM。
- conda-forge 提供的
scipy和pandaswheel 已完成静态链接,零编译、零link.exe参与 - 不要
conda install scipy后又pip install pandas——混合通道会导致numpy.dtype size changed错误并放大内存压力 - 验证是否干净:
python -c "import numpy; print(numpy.__file__)",路径应唯一指向 conda 环境下的site-packages
缓存污染比编译失败更隐蔽
pip cache purge 只清 HTTP 缓存,真正卡住的是 ~/.cache/pip/Cache/(Linux/macOS)或 %LOCALAPPDATA%\pip\Cache(Windows)里的半成品 wheel 和损坏的 METADATA。这些残留物会让 pip 在解析依赖时反复校验失败,陷入无限重试循环,且不输出任何日志。
- 手动删整个缓存目录比
pip cache purge更彻底 - 删完运行
pip cache info确认路径为空 - 若还在虚拟环境中卡住,别修修补补——直接
rm -rf venv && python -m venv venv,再重装
最容易被忽略的一点:你以为在虚拟环境里运行 pip install,实际调用的可能是系统 Python 的 pip,尤其当 shell 中 PATH 顺序错乱或用了 alias 时。先确认 which pip(Linux/macOS)或 where pip(Windows)输出是否指向虚拟环境内。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











