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

为何eval函数中的lambda无法捕获自定义locals字典中的变量?

为什么eval中定义的lambda无法捕获locals参数里的变量?

你遇到的这个问题,本质是Python函数(包括lambda)的变量解析机制和eval函数的参数行为共同作用的结果,咱们来一步步理清楚:

先明确核心现象

你尝试通过eval定义lambda时,将y放在locals参数中,调用lambda时会触发NameError:

>>> x = eval('lambda: print(y)', {}, {'y':2})
>>> x()
Traceback (most recent call last):
  File "<pyshell#75>", line 1, in <module>
    x()
  File "<string>", line 1, in <lambda>
NameError: name 'y' is not defined

但如果把y放在globals参数里,lambda就能正常运行:

>>> x = eval('lambda: print(y)', {'y': 2}, {})
>>> x()
2

背后的关键原因:lambda绑定的是eval的globals命名空间

Python中的函数(包括lambda表达式)在创建时,会自动绑定当前的全局命名空间作为自己的__globals__属性。而eval函数的globals参数,就是用来指定执行表达式时的全局命名空间——这个空间会被创建的lambda直接捕获为自身的__globals__。

而eval的locals参数只是一个临时的变量字典,仅在eval执行表达式的瞬间生效,用来解析表达式中的变量引用,但lambda作为一个独立的函数对象,并不会把这个临时的locals字典保存下来。当你后续调用lambda时,它会遵循Python的变量查找顺序:

  • 首先查找自身的局部变量(这里lambda没有定义局部变量)
  • 然后查找自己绑定的__globals__命名空间
  • 最后查找内置命名空间

所以当y只存在于eval的locals参数中时,lambda的__globals__里没有y,自然会报错;而把y放在globals里时,lambda的__globals__包含了这个变量,调用时就能正常找到。

验证结论:查看lambda的__globals__属性

你可以直接打印lambda的__globals__来确认这一点:

>>> x1 = eval('lambda: print(y)', {}, {'y':2})
>>> print(x1.__globals__)
{'__builtins__': <module 'builtins' (built-in)>}  # 没有y的踪迹

>>> x2 = eval('lambda: print(y)', {'y':2}, {})
>>> print(x2.__globals__)
{'y': 2, '__builtins__': <module 'builtins' (built-in)>}  # 明确包含y

补充:如何让lambda“捕获”locals里的变量?

如果你想让lambda获取eval的locals参数里的变量,可以用默认参数固化的技巧,在lambda定义时把变量值绑定到参数默认值上:

>>> x = eval('lambda y=y: print(y)', {}, {'y':2})
>>> x()
2

这里lambda的默认参数y=y会在eval执行时(也就是lambda创建时)从locals字典中取到y=2,并把这个值固定下来,后续调用时就不再依赖全局命名空间了。

内容的提问来源于stack exchange,提问作者user8426421

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:53:11