修改locals()字典后程序异常:全局/局部变量差异及pdb疑问
问题解答
1. 为什么num_0能打印,num_1不行?
- 全局作用域中,
locals()和globals()指向同一个字典。你通过locals()[f'num_{i}'] = i添加的num_0,本质是直接修改了全局变量字典。Python在全局作用域查找变量时,会直接遍历这个全局字典,所以print(num_0)能找到对应的变量。 - 函数
lc()属于局部作用域,Python的字节码编译器会在编译阶段静态分析函数内的局部变量,生成固定的局部变量表。你通过locals()添加的num_1,并不会被加入这个预先生成的局部变量表。当函数执行print(num_1)时,解释器会尝试通过局部变量表的索引去查找num_1,找不到就会抛出NameError,不会去查询locals()字典。
2. 为什么pdb中能打印num_1,但代码里的print(num_1)不行?
- 函数执行时的变量查找是基于编译期生成的局部变量表,是高效的直接索引访问,不会动态去查
locals()字典。 - 而pdb调试器的变量查找逻辑不同:它会先检查局部变量表,若找不到,会动态查询当前作用域的
locals()字典。你通过locals()添加的num_1存在于这个字典中,所以pdb能找到并打印它。
补充说明
Python官方文档明确指出,不要修改locals()返回的字典,尤其是在局部作用域中,这种操作的行为是未定义的,会导致类似你遇到的不一致问题。
内容的提问来源于stack exchange,提问作者x pie
相关产品推荐
相关产品推荐

