原因是list comp在运行时设置了自己的本地作用域。所以,如果你有类似的东西。
嵌套函数中定义的名称空间有问题。考虑以下代码:
def fun1():
CHARS = ['C','H','A','R','S']
def fun2():
C = 1
H = 2
A = 3
R = 4
S = 5
# just for warp-up, to ensure oneliners indeed work
a_list = [c for c in CHARS]
# the following structure works: makes [1,2,3,4,5]
eval_list = []
for c in CHARS:
eval_list.append(eval(c))
# this doesn't work. why?
oneliner_eval_list = [eval(c) for c in CHARS] # NameError: name 'C' is not defined
print('func2 ran without problem')
fun2()
print('func1 ran without problem')
fun1()
当我运行此程序时,oneliner for循环无法在本地命名空间中找到CHARS
,因此向上一级,在(fun1
的(封闭命名空间中找到了CHARS
。然而,当它这样做时,它忘记了自己的命名空间,并且找不到C
。
- 为什么
- 为什么多行for循环没有这样的问题
我使用Python 3。
END = 1
def func():
x = 0
lst = [locals() for i in range(END)]
print(lst)
func()
你得到
[{'.0': <range_iterator object at 0x000001ACC5BF79D0>, 'i': 0}]
当您调用eval
而不提供用作局部值时,它将使用当前作用域中的局部值
eval(source, globals=None, locals=None, /)
在这种情况下,它没有您的C,H,A,R,S
所以你可以通过做来解决它。
def fun1():
CHARS = ['C','H','A','R','S']
def fun2():
C = 1
H = 2
A = 3
R = 4
S = 5
local_vars = locals()
global_vars = globals()
# just for warp-up, to ensure oneliners indeed work
a_list = [c for c in CHARS]
# the following structure works: makes [1,2,3,4,5]
eval_list = []
for c in CHARS:
eval_list.append(eval(c))
# this doesn't work. why?
oneliner_eval_list = [eval(c, global_vars, local_vars) for c in CHARS]
print('func2 ran without problem')
fun2()
print('func1 ran without problem')
fun1()
您需要将它们作为全局变量。请在这里找到更新的代码,
def fun1():
CHARS = ['C', 'H', 'A', 'R', 'S']
def fun2():
global C, H, A,R,S # here is the update
C = 1
H = 2
A = 3
R = 4
S = 5
# just for warp-up, to ensure oneliners indeed work
a_list = [c for c in CHARS]
# the following structure works: makes [1,2,3,4,5]
eval_list = []
for c in CHARS:
eval_list.append(eval(c))
# this doesn't work. why?
oneliner_eval_list = [eval(c) for c in CHARS] # NameError: name 'C' is not defined
print('func2 ran without problem')
fun2()
print('func1 ran without problem')
fun1()
这将打印
func2 ran without problem
func1 ran without problem