You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:50:59