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

Python中eval嵌套lambda调用self报错:是否为语言Bug?

为什么eval中的lambda引用self会抛出NameError,直接写却正常?

这不是Python的Bug,而是eval的作用域规则和闭包捕获机制的差异导致的,核心原因如下:

  • 直接在方法内定义的lambda,是在当前方法的局部作用域中创建的。Python会把方法内的self作为cell变量处理,闭包(lambda)可以直接捕获这个变量,因此调用lambda时能正常访问self。
  • 用eval执行字符串中的lambda时,逻辑完全不同:
    1. eval默认会使用当前的全局作用域和局部作用域,但函数内的局部作用域在eval中是以字典形式被访问的。
    2. 字符串中的lambda在定义时,无法将eval字典里的self转化为可捕获的cell变量。当后续lambda被调用时,它会去全局作用域查找self,自然找不到,于是抛出NameError。

修复示例

你可以通过两种方式解决这个问题:

方式1:显式给lambda绑定self(通过默认参数)

class Foo:
    def __init__(self):
        print(eval('self.example(lambda s=self: s.pass_me("example"))'))

    def example(self, func):
        return func()

    def pass_me(self, arg1):
        print(arg1)

方式2:调用eval时显式传递局部作用域

class Foo:
    def __init__(self):
        print(eval('self.example(lambda: self.pass_me("example"))', globals(), locals()))

    def example(self, func):
        return func()

    def pass_me(self, arg1):
        print(arg1)

原代码对比

原报错代码示例1:

class Foo:
    def __init__(self):
        print(eval('self.example(lambda: self.pass_me("example"))'))

    def example(self, func):
        return func()

    def pass_me(self, arg1):
        print(arg1)

执行时会抛出NameError: name 'self' is not defined。

原正常运行代码示例2:

class Foo:
    def __init__(self):
        print(self.example(lambda: self.pass_me("example")))

    def example(self, func):
        return func()

    def pass_me(self, arg1):
        print(arg1)

因为lambda直接在__init__的局部作用域创建,能捕获self,所以运行正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:35:22