只需将 from distutils.core import setup 替换为 from setuptools import setup 即可兼容大部分项目,但需注意废弃参数、继承类变更、numpy 移除 numpy.distutils 等问题,并推荐迁移到 pyproject.toml。

直接替换 from distutils.core import setup 就能跑通?
大多数老项目里那行 from distutils.core import setup 确实只需改成 from setuptools import setup,接口几乎完全兼容。但别急着提交——setup() 调用里如果用了 distutils 特有参数(比如 use_2to3、convert_2to3_doctests),运行时会静默忽略或报错。这些参数在 setuptools 中早已废弃,且无替代实现。
常见踩坑点:
-
setup.py里写了cmdclass={'build_ext': MyBuildExt},而MyBuildExt继承自distutils.command.build_ext.build_ext→ 必须改为继承setuptools.command.build_ext.build_ext - 用了
numpy.distutils(尤其旧版 NumPy 项目)→ 这个子模块早在 NumPy 1.24 就被移除,Python 3.12 下必然失败,需升级 NumPy 并改用setuptools+pybind11或meson替代 - CI 流水线里执行
python setup.py bdist_wheel→ 改成pip wheel --no-deps --wheel-dir ./dist .更可靠,避免触发任何隐式distutils路径
为什么 pip install distutils 总是失败?
PyPI 上根本不存在叫 distutils 的包。所谓“兼容包”其实是误导——有人上传过同名包,但它是空壳或仅含文档,无法提供实际模块。Python 3.12 彻底剥离了 distutils 的 C 源码和 Python 实现,它不再是可 pip 安装的组件。
真正起作用的是 setuptools:它在内部模拟了部分 distutils 行为(比如 build_ext、install 命令),但只在被显式调用时加载。所以你看到的“恢复 distutils”本质是让 setuptools 提前注册这些命令。
操作建议:
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 确保虚拟环境里装的是
setuptools >= 65.5.0(低于此版本对 Python 3.12 支持不完整) - 不要手动
import distutils,哪怕只是为了检查是否存在——直接用import setuptools,然后调用setuptools.setup() - 若 PyCharm 报红
distutils找不到,不是解释器问题,而是 IDE 缓存未刷新;重启解释器或清掉.idea/caches目录即可
要不要立刻删掉 setup.py 改用 pyproject.toml?
不是必须,但越早做越省事。PEP 621 规范下,pyproject.toml 可以完全取代 setup.py 中 90% 的声明式配置(name、version、dependencies、entry_points 等)。剩下的构建逻辑(如自定义编译步骤)得靠 build-backend 指定,比如 setuptools.build_meta 或 hatchling.build。
迁移注意点:
-
setup.py里动态生成version(如读__init__.py)→ 改用dynamic.version+attr或call方式,在 toml 中声明 - 用了
MANIFEST.in→ 仍可保留,setuptools依然识别它;但推荐改用include/exclude写进 toml - 项目含 C 扩展且用
Extension类 →pyproject.toml不支持直接写 Python 对象,得抽到单独的构建脚本(如build.py),再通过build-backend引入
旧包装不上,又不能改源码,怎么办?
遇到这种包(比如某个 2018 年发布的私有工具、或锁死依赖的闭源 SDK),先查它有没有 wheel:运行 pip index versions package-name,看是否提供 cp312 标签的 wheel。有就直接装,绕过本地构建。
没有 wheel 时,临时解法只有两个:
- 降级 Python:用
pyenv install 3.11.9 && pyenv local 3.11.9切换,这是最稳的兜底方案 - 强制 patch:下载源码后,用
sed -i 's/from distutils.core import setup/from setuptools import setup/' setup.py(Linux/macOS),再pip install -e .。注意有些包的setup.py是生成的,得找上游模板改
别信“安装 distutils 兼容包”这类说法——它要么是无效包,要么只是把 setuptools 的部分代码重打包,反而可能引入版本冲突。真正的分水岭不在能不能装上,而在你愿不愿意接受:从 Python 3.12 开始,distutils 就是没了,不是藏起来了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










