Skip to main content
 首页 » 编程设计

python之NameError:名称 'self' 未在 EXEC/EVAL 中定义

2025年05月04日7findumars

我正在编写一些代码,但有一部分出错了。 但是我找不到错误发生的原因。

代码(样例;与报错部分类似):

class Test: 
def __init__(self,a=0): 
    self.x = a 
    self.l = [2**x for x in range(a)]  #<--- self.l = [1,2,4,8,16] 
    self.base() 
 
def base(self): 
    expr = "self.l{0} = [self.l[x]+{0} for x in range(self.x)]" #<--- when i=4, self.l4 = [5,6,8,12,20] 
    for i in range(self.x): 
        exec(expr.format(i)) 
 
w = Test(5) 
print(w.l4) 

所以我想我明白了:

[5, 6, 8, 12, 20] 

但是,

File "D:/Documents and Settings/Desktop/py/py/test2.py", line 12, in <module> 
  w = Test(5) 
File "D:/Documents and Settings/Desktop/py/py/test2.py", line 5, in __init__ 
  self.base() 
File "D:/Documents and Settings/Desktop/py/py/test2.py", line 10, in base 
  exec(expr.format(i)) 
File "<string>", line 1, in <module> 
File "<string>", line 1, in <listcomp> 
 
NameError: name 'self' is not defined 

(抱歉英语不好)

请您参考如下方法:

如果您使用 for 循环而不是列表理解

它会起作用。

class Test: 
    def __init__(self,a=0): 
        self.x = a 
        self.l = [2**x for x in range(a)]  #<--- self.l = [1,2,4,8,16] 
        self.base() 
 
    def base(self): 
        # expr = "self.l{0} = [self.l[x]+{0} for x in range(self.x)]" #<--- when i=4, self.l4 = [5,6,8,12,20] 
        expr = ''' 
self.l{0} = [] 
for x in range(self.x): 
    self.l{0}.append(self.l[x]+{0}) 
''' 
        for i in range(self.x): 
            expr_formated = expr.format(i) 
            print(expr_formated) 
            exec(expr_formated) 
 
w = Test(5) 
print(w.l4) 

列表理解实际上是使用lamda函数,正如你在the python document中看到的那样. squares = [x**2 for x in range(a)] 实际上是 squares = list(map(lambda x: x**2, range(a)))。 (编辑:最近我发现这不准确,参见 my question ,它们不一样,但它们的工作方式相似;也许仍然可以使用 lambda 来理解this if doesn't want to refer to python assembly) 但是,在 exec() 中创建函数对象(此处为 lamda 函数)会导致问题。我发question这里解释了为什么创建函数对象不能按预期工作。简而言之,将定义的lamda函数的__closure__设置为None,使得调用lamda函数时变量a不可用。

如果你坚持使用lambda函数。

还有另一种解决方案。请引用my answer到前面提到的问题以获取更多信息。

class Test: 
    def __init__(self,a=0): 
        self.x = a 
        self.l = [2**x for x in range(a)]  #<--- self.l = [1,2,4,8,16] 
        self.base() 
 
    def base(self): 
        expr = """ 
def closure_helper_func(self): 
    self.l{0} = [self.l[x]+{0} for x in range(self.x)] 
closure_helper_func(self)""" #<--- when i=4, self.l4 = [5,6,8,12,20] 
        for i in range(self.x): 
            expr_formated = expr.format(i) 
            # print(expr_formated) 
            exec(expr_formated) 
 
w = Test(5) 
print(w.l4)