I was coding something, and there was an error in one part. But I can't find why the error occurs.
Code (Sample; similar to the error part):
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)
So I thought that I get this:
[5, 6, 8, 12, 20]
BUT,
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
(Sorry for bad English)
it will works.
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)
The list comprehension is actually using lamda function, as you can see in the python document . squares = [x**2 for x in range(a)]
is actually squares = list(map(lambda x: x**2, range(a)))
. (EDIT: recently I find that this is not accurate, see my question , they are not the same, but they work in a similar way;perhaps one can still uses the lambda
to understand this if doesn't want to refer to python assembly) However, creating a function object (lamda function here) inside the exec()
will results in problems. I post question here explaining why creating a function object doesn't work as expected. In short, the __closure__
of the defined lamda function is set to None, making the varible a
unavailable when the lamda function is called.
There is also another solution. Please refer to my answer to previous mentioned question for more information.
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' is a special class variable, only used internal, can't read outside a class. The first example needs a return value.
There's no need for eval or exec here.
for i in range(self.x):
setattr(self, "l{}".format(i), [self.l[x]+i for x in range(self.x)])
Although I don't know why you want to do this; better to keep it as a list rather than dynamically set attributes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.