Python中locals()函数异常行为:生成器表达式中出现KeyError问题
Python中locals()函数异常行为:生成器表达式中出现KeyError问题
我太懂你的困惑了——明明直接调用locals()['RAPPORT']能正常输出0.0,把同样的写法放进生成器表达式里就突然报KeyError,这反差真的让人摸不着头脑!
问题根源:生成器表达式的嵌套作用域
核心原因在于:生成器表达式会创建自己的独立嵌套作用域,当你在生成器内部调用locals()时,它指向的是生成器这个小环境自己的局部命名空间,而不是你定义RAPPORT、COMPA这些变量的外部作用域(在交互模式顶层,这个外部作用域其实就是全局作用域,locals()和globals()是同一个)。
你直接执行print(locals()['RAPPORT'])时,locals()访问的是当前顶层的全局命名空间,自然能找到变量;但生成器里的locals()是生成器自己的空命名空间,根本没有RAPPORT、COMPA这些键,所以抛出KeyError是必然的。
至于Python2和Python3报错的键不一样,只是生成器迭代时的顺序差异(Python3.7+字典才保序,之前版本迭代顺序不确定),本质问题完全相同。
解决办法
给你几个简单可行的修复方案:
- 方案1:提前拷贝外部作用域的变量字典
把外部的locals()(或globals())提前拷贝到一个普通字典里,生成器里直接用这个拷贝好的字典:
condition ={'RAPPORT': 1, 'COMPA': 0.815, 'varie': 'N_GRAIN'} N_GRAIN, RAPPORT, COMPA, ACC, FREQ = 0.,0.,0.,0.,0. # 提前拷贝外部作用域的变量 external_vars = locals().copy() match = all(condition[key] == external_vars[key] for key in condition if key != 'varie')
- 方案2:直接引用变量名(或用globals())
如果是在顶层交互模式,globals()和locals()是同一个,你可以直接用globals()替代生成器里的locals():
match = all(condition[key] == globals()[key] for key in condition if key != 'varie')
如果是在函数内部,也可以提前把需要的变量提取出来,或者直接通过变量名引用(Python会自动从外部作用域查找)。
- 方案3:显式构造变量映射字典
如果变量不多,也可以直接手动构造包含目标变量的字典,避免作用域混淆:
var_map = {'RAPPORT': RAPPORT, 'COMPA': COMPA} match = all(condition[key] == var_map[key] for key in condition if key != 'varie')
备注:内容来源于stack exchange,提问作者WillMP
相关产品推荐
相关产品推荐

