如何让get_dynamic_re返回含外围作用域变量的dict?解决KeyError
问题
get_dynamic_re 是一个创建 DynamicScope 对象并返回其成员 d(字典类型)的函数。需要实现让该函数将外围作用域 outer 中的变量键值对传入 DynamicScope 的 d,使其返回包含这些变量的字典,但当前运行时触发 KeyError 错误。
原代码实现
DynamicScope 定义与 get_dynamic_re 函数
from collections.abc import Iterator, Mapping def get_dynamic_re(): ds = DynamicScope() return ds.d class DynamicScope(Mapping): d = {} def __init__(self) -> None: pass def __getitem__(self, __key: str) -> any: # 获取字典中的项 if __key in self.d: return self.d[__key] else: raise NameError def __iter__(self) -> Iterator: # 遍历字典 return self.d.__iter__() def __len__(self) -> int: # 获取字典长度 return self.d.__len__()
调用代码
def outer(): a = "outer_a" b = "outer_b" c = "outer_c" return get_dynamic_re() if __name__ == "__main__": dre = outer() print(f"{dre['a']=}") print(f"{dre['b']=}") print(f"{dre['c']=}")
报错信息
回溯(最近的调用最后): 文件"y",第13行,在<module>中 print(f"{dre['a']=}") KeyError: 'a'
解决方案
要实现动态获取外围作用域变量,需借助Python的inspect模块获取调用栈信息,提取上层作用域的局部变量并传入DynamicScope。修改后的代码如下:
修改后完整代码
from collections.abc import Iterator, Mapping import inspect def get_dynamic_re(): # 获取调用当前函数的上层栈帧(即outer函数的作用域) caller_frame = inspect.currentframe().f_back # 复制上层作用域的局部变量,避免后续修改影响 caller_locals = caller_frame.f_locals.copy() # 传入局部变量初始化DynamicScope ds = DynamicScope(caller_locals) return ds.d class DynamicScope(Mapping): def __init__(self, init_data: dict) -> None: # 将类属性d改为实例属性,确保每个实例独立持有字典 self.d = init_data def __getitem__(self, __key: str) -> any: if __key in self.d: return self.d[__key] else: raise NameError(f"名称 '{__key}' 未找到") def __iter__(self) -> Iterator: return iter(self.d) def __len__(self) -> int: return len(self.d)
核心修改说明
- 引入inspect模块:通过
inspect.currentframe().f_back获取调用get_dynamic_re的上层函数栈帧,从而拿到outer的局部变量 - 重构DynamicScope初始化:将类属性
d改为实例属性,通过构造函数接收外部传入的变量字典,避免多个实例共享同一字典 - 完善错误提示:给
NameError添加具体的键名信息,便于调试
运行修改后的代码,将输出:
dre['a']='outer_a' dre['b']='outer_b' dre['c']='outer_c'
内容的提问来源于stack exchange,提问作者CodingMonster
相关产品推荐
相关产品推荐

