为什么Python 3.12不再包含distutils_学习使用setuptools进行模块打包

Python 3.12 中 distutils 已被彻底移除,必须将 from distutils.core import setup 替换为 from setuptools import setup,并升级 setuptools ≥65.5.0,禁用废弃参数,继承类改为 setuptools 路径,CI 改用 pip wheel。

distutils 在 Python 3.12 中已被彻底移除,不是“找不到”,而是根本不存在——标准库源码里删干净了。你无法通过 pip install distutils 恢复它,PyPI 上那个同名包是空壳,装了也没用。

setup.py 还在用 from distutils.core import setup?立刻改掉

这种写法在 Python 3.12 下直接报 ModuleNotFoundError: No module named 'distutils'
setuptools.setup 是唯一兼容且受支持的替代入口:

  • 把所有 from distutils.core import setup 替换为 from setuptools import setup
  • 如果用了 find_packages()find_namespace_packages(),它们现在只属于 setuptools,不来自 distutils
  • 不要保留 use_2to3=Trueconvert_2to3_doctests 等已废弃参数,setuptools >= 65.5.0 会忽略并警告

旧:

from distutils.core import setup
setup(name='foo', ...)

新:

from setuptools import setup
setup(name='foo', ...)

自定义构建命令(如 build_ext)继承链必须指向 setuptools

如果你写了类似 cmdclass={'build_ext': MyBuildExt},而 MyBuildExt 继承自 distutils.command.build_ext.build_ext,运行时会失败——类路径已失效。

  • 改为继承 setuptools.command.build_ext.build_ext
  • 若项目还依赖 numpy.distutils(比如旧版 NumPy 扩展),注意:该模块早在 NumPy 1.24 就被标记为 deprecated,Python 3.12 下必然崩溃;必须升级 NumPy 并迁移到 setuptools + pybind11meson
  • build_pysdistinstall 等命令同理,全部从 setuptools.command 下导入

CI/CD 流水线里还在跑 python setup.py bdist_wheel?换成 pip wheel

python setup.py bdist_wheel 会隐式触发 distutils 路径,即使你改了 setup.py,某些底层调用仍可能 fallback 到已删除模块。

  • 改用 pip wheel --no-deps --wheel-dir ./dist .,这是 PEP 517 兼容的标准方式
  • 确保 CI 环境中安装的是 setuptools >= 65.5.0(低于此版本对 Python 3.12 的 build_ext 支持不完整)
  • 虚拟环境创建后,第一时间运行 pip install --upgrade setuptools,别依赖 venv 默认附带的旧版

PyCharm 报红 distutils 找不到?不是解释器问题,是缓存没刷

IDE 显示红色波浪线、提示 unresolved reference,并不代表代码真会运行失败。

  • 这是 PyCharm 基于当前解释器环境做的静态分析,但它可能还缓存着旧 Python 版本的 stubs
  • 解决方法只有两个:File → Reload project from Disk,或手动删掉 .idea/caches 目录后重启
  • 不要试图在项目里加 try/except ImportError 去“兼容” distutils——它不在了,伪装没意义

最常被忽略的一点:有些项目把 setup.py 当脚本直接执行(比如 python setup.py build),这在 Python 3.12 下已不可行。所有构建动作都应通过 pipbuild 工具驱动,而不是直调 setup.py

Python 3.14.3

微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。

相关推荐:

如何用Python自动化操作Word文档生成报告_利用python-docx模块

python-docx新建文档默认页边距1英寸、字体Calibri 11pt,因不加载normal.dotm模板而用硬编码值;需显式设置section边距和Normal样式字体;add_paragraph()自带段前段后间距致空行;cell.text会清空格式,应操作paragraphs[0].runs;样式名须严格匹配。 python-docx 能生成格式规整的 Word 报告,但不能读取或修改...

如何使用Python中的calendar模块判断闰年_调用isleap函数

应直接使用 calendar.isleap() 判断闰年,它准确实现公历规则、线程安全、性能优且自 Python 2.3 起稳定兼容,避免手写逻辑出错或误用类型。 直接用 calendar.isleap() 判定闰年,别自己写逻辑 Python 的 calendar.isleap() 是最可靠、最省事的闰年判断方式。它封装了格里高利历(公历)全部规则:能被 4 整除但不能被 100 整除,或能被 ...

如何在Python中删除包含特定字符的行_利用~运算符与str.contains

str.contains默认遇NaN返回NaN,导致布尔索引报错;加na=False可将NaN统一转为False,确保筛选安全。 str.contains 为什么默认不匹配空值会报错 直接对含 NaN 的列调用 str.contains("x"),Pandas 默认抛出 TypeError: expected a string object, not float。这是因为 NaN 在底层是浮点类型...

如何在Python中测试多线程并发安全性_利用pytest结合threading模块调试

pytest测多线程安全会“测不准”是因为其单线程执行机制导致测试函数返回即判定完成,后台线程可能未结束;必须用join显式同步、Event/Lock制造竞态、捕获线程异常并共享被测对象。 为什么直接用 pytest 测多线程安全会“测不准” 因为 pytest 默认是单线程执行测试函数,即使你在测试里手动启动多个 threading.Thread,它也不会自动等待所有线程结束就判定测试通过——t...

如何计算Python中代码块的执行时间_使用timeit模块或time.perf_counter

该用 time.perf_counter() 时:只想测单次代码实际耗时,如调试算法分支、验证 API 延迟或粗略比对逻辑耗时;它返回纳秒级单调递增时间,不受系统时钟影响,是官方推荐的经过时间测量首选。 直接用 time.perf_counter() 测单次代码块最准,timeit 适合测小函数的重复执行均值——别拿 timeit 去包带 I/O 或状态变更的代码,结果会失真。 什么时候该用 ti...

怎样在Python Tkinter中使用自定义字体_通过tkFont模块注册本地字体文件

Python 3 中 tkFont 已被移除,需改用 tkinter.font;Tkinter 不支持直接加载本地字体文件,必须先通过系统安装字体,再用 font.families() 确认名称后使用。 tkFont 在 Python 3 中已不存在,改用 font 模块 Python 3.0 起 tkFont 模块被移除,所有字体操作统一由 tkinter.font 模块提供。如果你在代码里写了...

如何在 Python 中通过命名空间包简化 src 布局子模块的导入路径

本文介绍如何利用 Python 命名空间包(namespace package)机制,优雅地将具有 src 布局的外部包(如 pack1)作为子模块集成到主包(如 superpackage)中,从而实现 from superpackage.pack1 import module1 这类简洁导入,避免冗长路径(如 superpackage.pack1.src.pack1.module1)和侵入式修改...

如何检查字符串中是否包含列表中的任意元素

本文介绍在Python中高效判断字符串是否包含列表中任一元素的多种方法,重点解析any()函数的正确用法与常见误区,并对比in操作符的适用场景。 本文介绍在python中高效判断字符串是否包含列表中任一元素的多种方法,重点解析`any()`函数的正确用法与常见误区,并对比`in`操作符的适用场景。 在Python开发中,一个常见需求是:判断某个字符串是否等于列表中的某一项(即“精确匹配”),而非检...

如何检查字符串中是否包含列表中的某个元素

本文介绍在Python中高效判断字符串是否包含列表中任意元素的多种方法,重点纠正any()误用场景,并提供简洁、安全、可扩展的解决方案。 本文介绍在python中高效判断字符串是否包含列表中任意元素的多种方法,重点纠正`any()`误用场景,并提供简洁、安全、可扩展的解决方案。 在Python中,常见的需求是:给定一个字符串(如 password = "B")和一个字符/字符串列表(如 prac ...