__module__ 返回模块名字符串而非模块对象,易因相对导入、命名空间包等导致 importlib.import_module 失败;推荐优先用 inspect.getmodule() 获取已加载模块,仅需字符串时才读 __module__。

__module__ 属性返回的是模块名字符串,不是模块对象
直接访问 cls.__module__ 得到的只是字符串(如 "myapp.models"),不是可导入的模块。很多人误以为能直接用它做 importlib.import_module(cls.__module__) 就万事大吉,但实际中常因相对导入、命名空间包或未加载模块而失败。
常见错误现象:ModuleNotFoundError: No module named 'xxx',尤其在单元测试、打包后执行或使用 zipimport 时更频繁。
- 先检查该模块名是否已在
sys.modules中:用sys.modules.get(cls.__module__) - 若不存在,再尝试
importlib.import_module(cls.__module__),并捕获ImportError - 注意:Django 的模型类可能来自
models.py,但__module__值可能是"myapp.models",而实际模块路径受INSTALLED_APPS和导入方式影响
区分 __module__ 和 inspect.getmodule() 的适用场景
inspect.getmodule(obj) 是更稳妥的替代方案——它基于对象的内存地址反查已加载模块,不依赖字符串解析,能正确处理动态生成类、交互式环境(如 IPython)或 exec() 创建的对象。
但它的限制也很明确:仅对已成功导入并驻留内存的模块有效;如果类定义在未执行的字符串里(比如从数据库读取代码再 exec),getmodule() 会返回 None。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 优先用
inspect.getmodule(cls)获取模块对象(推荐用于调试、日志、反射场景) - 只在需要模块名字符串时才读
cls.__module__(例如拼接日志前缀、序列化元数据) - 二者结果不一致时(极少见),以
getmodule()返回的模块对象为准——__module__可被手动篡改,不可信
__module__ 在多文件继承链中可能指向“定义处”而非“使用处”
Python 类的 __module__ 固定为**首次定义该类的模块**,不会随子类所在位置变化。这意味着:父类在 core.py 定义,子类在 api/views.py 中继承,子类的 __module__ 仍是 "core",而非 "api.views"。
这导致按模块组织文档、自动注册或权限控制时出错——你以为某个 API 视图类属于 api 模块,但它 __module__ 却是 "core"。
- 用
cls.__qualname__辅助判断层级(如"APIViewSet.NestedSerializer") - 若需获取“子类声明所在模块”,得遍历
inspect.getfile(cls)对应的文件路径,再映射回模块名(需配合pkgutil.iter_modules()或项目配置) - 避免仅靠
__module__做模块级路由或插件发现逻辑
打包工具(PyInstaller / cx_Freeze)可能导致 __module__ 不可用
某些打包工具会重写模块导入逻辑,使 __module__ 字符串仍存在,但对应模块无法通过标准方式导入。典型表现是:打印 cls.__module__ 正常,但 importlib.import_module(...) 报错,且 inspect.getmodule(cls) 返回 None。
这不是 bug,而是打包后模块加载机制变更所致。此时唯一可靠信息是 cls.__name__ 和 inspect.getfile(cls)(如果可用)。
- 打包前测试
importlib.import_module(cls.__module__)是否真能成功导入 - 在 PyInstaller 中启用
--collect-all或显式添加模块到HIDDENIMPORTS - 生产环境慎用依赖
__module__动态导入的热插拔逻辑
__module__,而是拿到之后你打算拿它干什么——字符串本身没副作用,但后续的 import、反射、路径推导,每一步都可能因环境差异悄悄失效。Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










