直接修改__builtins__无效且危险,因其为只读映射,变更不跨模块生效;可靠方式是通过sys.modules注入并显式导入,或封装为可安装包,遵循import约定。

直接修改 __builtins__ 是危险且无效的
不能靠往 __builtins__ 里塞类来让所有模块“自动”继承或识别它。Python 启动后,__builtins__ 是只读映射(CPython 中是 dict 的代理),强行赋值会失败或被忽略;即使临时改了,新导入的模块也不会继承这个变更——它们的全局命名空间是在 import 时独立构建的,不共享运行时修改的 __builtins__。
真正生效的方式:用 sys.modules 注入并确保导入路径一致
想让某个基类像内置类型一样随处可用,唯一可靠路径是把它注册进 sys.modules,并让所有代码通过标准 import 引用它。比如你想让 BaseModel 像 object 那样“默认存在”,实际得让它成为某个已加载模块的一部分:
- 定义类后,手动塞进
sys.modules,例如:sys.modules['mybase'] = types.SimpleNamespace(BaseModel=BaseModel) - 所有使用方必须显式写
from mybase import BaseModel,而不是指望它自动出现在全局作用域 - 如果硬要模拟“全局可用”,可在主入口(如
__main__.py)中执行globals()['BaseModel'] = BaseModel,但这只影响当前模块,对其他模块完全无效
常见错误:以为 __builtins__.__dict__.update() 能跨模块生效
这种写法看起来能成功:
__builtins__.__dict__.update({'MyBase': MyBase})
但结果只是给当前帧的 builtins 字典加了个键,下个模块 import 时重新获取 __builtins__,里面没有这个键。更糟的是,在某些 Python 版本或嵌入环境中,__builtins__ 根本不是 dict,而是模块对象,.update() 直接抛 AttributeError。
立即学习“Python免费学习笔记(深入)”;
替代方案:用 site-packages + __init__.py 暴露接口
长期维护、多模块复用的正确做法是把它做成一个最小包:
- 建目录
mybase/,含__init__.py,里面写from .core import BaseModel -
pip install -e .安装到环境,所有模块都能稳定from mybase import BaseModel - 若需“伪内置”,可在启动脚本开头加
import mybase; globals().update(vars(mybase)),但仅限当前模块,且污染命名空间,不推荐
真正的全局基类不存在于注入技巧里,而在于设计规范和 import 约定。别绕开 import,它才是 Python 的全局契约。


















