NameError: name 'self' is not defined IN EXEC/EVAL
NameError: name 'self' is not defined IN EXEC/EVAL
我正在编写一些代码,其中有一部分出错了。
但是我找不到错误发生的原因。
代码(样例;与报错部分类似):
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
(抱歉英语不好)
此处不需要 eval 或 exec。
for i in range(self.x):
setattr(self, "l{}".format(i), [self.l[x]+i for x in range(self.x)])
虽然我不知道你为什么要这样做;最好将其保留为列表而不是动态设置属性。
如果您使用 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)]
is actually squares = list(map(lambda x: x**2, range(a)))
. However, creating a function object (lamda function here) inside the exec()
will results in problems. I post 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)
'self'是一个特殊的class变量,只能在内部使用,不能在class外部读取。第一个示例需要一个 return 值。
我正在编写一些代码,其中有一部分出错了。 但是我找不到错误发生的原因。
代码(样例;与报错部分类似):
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
(抱歉英语不好)
此处不需要 eval 或 exec。
for i in range(self.x):
setattr(self, "l{}".format(i), [self.l[x]+i for x in range(self.x)])
虽然我不知道你为什么要这样做;最好将其保留为列表而不是动态设置属性。
如果您使用 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)]
is actually squares = list(map(lambda x: x**2, range(a)))
. However, creating a function object (lamda function here) inside the exec()
will results in problems. I post 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)
'self'是一个特殊的class变量,只能在内部使用,不能在class外部读取。第一个示例需要一个 return 值。