Python 3.12 移除 imp、distutils 等模块是按 PEP 594 主动清理,非 bug;这些模块被列为“dead batteries”并彻底删除,PyPI 上无对应包,pip install 无效,需代码级迁移适配。

Python 3.12 移除 imp、distutils 等模块,不是 bug,是按 PEP 594 主动清理——这些模块已被标记弃用多年,3.12 是最终移除节点。
PEP 594 定义了哪些模块被归为 “dead batteries”
该 PEP 明确将一批长期无人维护、功能重叠、存在安全隐患或使用率极低的模块列为“已死亡电池”(dead batteries),并推动其从标准库物理删除。被移除的包括:
-
imp:因importlib已完全覆盖其功能,且imp.load_source()等接口不安全 -
distutils:构建逻辑混乱、API 不一致,早被setuptools取代;其子模块如numpy.distutils也同步失效 -
aifc、audioop、cgi、imghdr、mailcap、ossaudiodev、sunau、telnetlib、uu等:使用场景萎缩,有更现代、更安全的替代方案(如http.server替代部分cgi逻辑)
为什么不能 pip install distutils 或 imp
这不是安装问题,而是设计事实:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- PyPI 上没有合法的
distutils或imp包——CPython 源码中这两个模块的 .py 文件已被彻底删除,连 stub 都不剩 -
pip install setuptools能“恢复”部分distutils行为,是因为setuptools在运行时动态注册了兼容命令(如build_ext),但它不提供distutils模块本身 - 试图
import distutils或import imp会直接触发ModuleNotFoundError,无绕过可能
迁移时最常踩的三个坑
实际改代码时,表面替换容易,深层耦合难察觉:
立即学习“Python免费学习笔记(深入)”;
- 直接搜索
from distutils并替换成from setuptools不够——若用了distutils.version.LooseVersion,得换用packaging.version.parse(),否则版本比较逻辑会错 -
setup.py中继承自distutils.command.build_ext的自定义类,必须同步改为继承setuptools.command.build_ext.build_ext,否则在 Python 3.12 下构造失败 - 旧项目里混用
numpy.distutils(尤其带 C 扩展的科学计算包),不能只升级setuptools——必须升级numpy≥ 1.26,并改用pybind11或meson构建系统
真正麻烦的从来不是“找不到模块”,而是那些没报错但行为已变的调用——比如 distutils.dir_util.copy_tree() 的符号链接处理逻辑和 shutil.copytree(..., symlinks=True) 不完全等价,静默差异会在部署时暴露。

















