为什么导入时globals()['__builtins__']类型变化?Python会为每个模块新建__builtins__对象吗?
问题现象背后的CPython实现机制
你观察到的差异是CPython解释器为了优化内置名称查找效率特意设计的行为,和模块的运行上下文直接相关。
核心原理
- CPython中,每个模块的全局命名空间里的
__builtins__是一个内部别名,它的类型由模块的运行模式决定:- 当模块作为入口脚本直接运行(也就是作为
__main__模块执行)时,globals()['__builtins__']直接指向标准的builtins模块对象本身 - 当模块被其他模块导入运行时,
globals()['__builtins__']指向的是builtins模块的__dict__属性,也就是存储所有内置函数、异常、类型的字典
- 当模块作为入口脚本直接运行(也就是作为
- 这个设计的目的是降低内置名称的查找开销:模块内访问
print、len这类内置名称时,解释器在全局命名空间找不到对应名称后,不需要额外多做一次「获取__builtins__模块→获取模块的__dict__」的操作,直接访问别名指向的字典就能完成查找,提升执行效率。
验证逻辑
你可以通过以下代码验证这个逻辑:
# 模块A import builtins foo = globals()['__builtins__'] # 直接运行时输出 True,被导入时输出 False print("__builtins__ is builtins module?", foo is builtins) # 直接运行时输出 False,被导入时输出 True print("__builtins__ is builtins.__dict__?", foo is builtins.__dict__)
注意:
__builtins__是解释器内部使用的别名,不属于公开规范,业务代码不建议直接依赖这个变量的类型,需要使用内置模块时应该显式import builtins获取稳定的模块对象。
内容的提问来源于stack exchange,提问作者Nick S
相关产品推荐
相关产品推荐

