根本原因是Python 3.12移除了pkgutil.ImpImporter并默认不包含distutils,而旧版setuptools(≤66.x)仍依赖二者;推荐安装setuptools==67.0.0以兼容ImpImporter移除问题,同时避免68.0+版本引发的绝对路径校验等新错误。

setuptools 在 Python 3.12 中安装报错,根本原因不是它本身坏了,而是它和 Python 3.12 的“新规矩”撞上了——Python 3.12 移除了 pkgutil.ImpImporter,同时默认不带 distutils,而旧版 setuptools(尤其是 ≤66.x)仍依赖这两者。
你遇到的典型错误,比如:
AttributeError: module 'pkgutil' has no attribute 'ImpImporter'ModuleNotFoundError: No module named 'distutils'
都不是你的环境配置错了,是版本链上某环没跟上。
setuptools 安装失败时的常见错误现象
- 执行
pip install setuptools直接抛AttributeError,甚至 pip 自身都起不来 - 创建完 Python 3.12 虚拟环境后,
pip list报错或显示空,pip install提示 “setuptoolsnot found” - PyCharm 或 Poetry 创建的虚拟环境里,包管理功能灰掉,提示 “Python packaging tool ‘setuptools’ not found”
- 即使手动下载 wheel 安装,也可能卡在构建阶段,因为底层调用了已移除的
distutils.sysconfig
这些现象背后共用一个事实:Python 3.12 的标准库精简了,但很多工具还没完成适配迁移。
立即学习“Python免费学习笔记(深入)”;
为什么 python -m ensurepip --upgrade 常常无效
ensurepip 在 Python 3.12 中的行为变了:
- 它不再默认安装
setuptools和wheel(只装pip) - 即使加了
--upgrade,也仅升级已存在的包,而如果虚拟环境里压根没setuptools,它不会主动补上 - 某些发行版(如 Anaconda、某些 Linux 包管理器安装的 Python)会跳过
ensurepip的完整初始化
所以,别依赖它自动修复。更可靠的做法是:
- 激活虚拟环境后,显式运行:
python -m pip install --upgrade pippython -m pip install --upgrade setuptools==67.0.0python -m pip install --upgrade wheel
setuptools==67.0.0 是目前被验证能绕过 ImpImporter 报错的最后一个兼容版本;高于它(如 68.0+)又会因绝对路径校验等问题导致 h5py、d2l 等库构建失败。
Python 3.12 下 setuptools 的实际使用场景与兼容性取舍
你不需要、也不应该盲目追求“最新版”:
- 如果只用纯 Python 包(如
requests、click),setuptools>=67.0.0基本够用 - 如果要装含 C 扩展的包(
numpy、h5py、capstone、d2l),必须注意:-
numpy1.26+ 已支持 Python 3.12,但需搭配setuptools>=68.0.0+pyproject.toml构建方式 -
h5py3.10.0 及更早源码包(sdist)与setuptools>=68.0不兼容,会报ValueError: path ... cannot be absolute -
d2l依赖的旧构建逻辑,仍会触发pkgutil.ImpImporter调用
-
这意味着:同一 Python 3.12 环境里,你可能得为不同包切换 setuptools 版本——这很麻烦,也是为什么很多人最终选择降级到 Python 3.11。
真正容易被忽略的一点是:Python 3.12 的虚拟环境是“干净过头”了。它不预装 distutils,也不强制捆绑 setuptools,等于把打包基础设施的决策权交还给用户。这不是 bug,是设计;但对日常开发来说,它把“能跑”和“能装”拆成了两个需要分别确认的动作。


















