Python中局部变量访问比全局变量快,因为局部变量通过栈帧数组的固定索引O(1)访问,而全局变量需字典哈希查找,开销更大;编译期确定作用域并生成LOAD_FAST或LOAD_GLOBAL指令。

Python 中局部变量访问比全局变量快,核心原因是局部变量存储在栈帧的固定偏移位置,而全局变量需要通过字典查找。
局部变量使用快速索引访问
函数执行时,Python 为每次调用创建一个栈帧(frame),其中包含一个 locals 数组(实际是 PyFrameObject 的 f_localsplus 字段)。所有局部变量按定义顺序被分配到这个数组的固定索引上。读取 a = x 时,解释器直接按索引(如 0、1、2)从数组中取值,是 O(1) 的内存寻址操作,无需哈希计算或键匹配。
全局变量依赖字典查找
全局变量(包括模块级变量)存放在模块的 __dict__ 字典中。每次访问 global_var,Python 需要: - 计算变量名的哈希值 - 在字典哈希表中定位桶(bucket) - 遍历桶内可能的冲突项,逐个比对字符串键 这个过程平均 O(1),但常数开销远大于数组索引,尤其在频繁访问时差异明显。
名字解析发生在编译期
Python 编译函数时就确定了每个变量的作用域。如果某名字在函数内被赋值(哪怕只在 if 分支里),它就被标记为局部变量。编译器生成 LOAD_FAST 指令(对应局部)或 LOAD_GLOBAL 指令(对应全局)。你可以用 dis.dis(func) 查看字节码验证:前者操作数是索引整数,后者操作数是变量名对象。
避免意外触发全局查找
以下写法会让本该是局部的变量退化为全局查找: - 在赋值前读取同名变量(如先 print(x),再 x = 1)→ 触发 UnboundLocalError 或隐式全局引用 - 使用 exec() 或 eval() 动态引入变量 → 破坏编译期作用域判断 - 显式声明 global x → 强制走全局路径 保持变量“先定义、后使用”,并避免动态作用域操作,能稳定享受局部变量速度优势。










