def num():
return [lambda x: i * x for i in range(4)]
print([m(2) for m in num()])
详解:
def func():
fun_lambda_list = []
for i in range(4):
def lambda_(x):
print('Lambda函数中 i {} 命名空间为:{}:'.format(i, locals()))
return x*i
fun_lambda_list.append(lambda_)
print('外层函数 I 为:{} 命名空间为:{}'.format(i, locals()))
return fun_lambda_list
fl = func()
fl[0](1)
fl[1](1)
fl[2](1)
fl[3](1)
运行结果:
外层函数 I 为:0 命名空间为:{'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000020A45679288>], 'lambda_': <function func.<locals>.lambda_ at 0x0000020A45679288>, 'i': 0}
外层函数 I 为:1 命名空间为:{'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000020A45679288>, <function func.<locals>.lambda_ at 0x0000020A45679318>], 'lambda_': <function func.<locals>.lambda_ at 0x0000020A45679318>, 'i': 1}
外层函数 I 为:2 命名空间为:{'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000020A45679288>, <function func.<locals>.lambda_ at 0x0000020A45679318>, <function func.<locals>.lambda_ at 0x0000020A456793A8>], 'lambda_': <function func.<locals>.lambda_ at 0x0000020A456793A8>, 'i': 2}
外层函数 I 为:3 命名空间为:{'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000020A45679288>, <function func.<locals>.lambda_ at 0x0000020A45679318>, <function func.<locals>.lambda_ at 0x0000020A456793A8>, <function func.<locals>.lambda_ at 0x0000020A45679438>], 'lambda_': <function func.<locals>.lambda_ at 0x0000020A45679438>, 'i': 3}
Lambda函数中 i 3 命名空间为:{'x': 1, 'i': 3}:
Lambda函数中 i 3 命名空间为:{'x': 1, 'i': 3}:
Lambda函数中 i 3 命名空间为:{'x': 1, 'i': 3}:
Lambda函数中 i 3 命名空间为:{'x': 1, 'i': 3}:
原理:
i 在外层作用域
lambda x: x*i
为内层(嵌)函数,他的命名空间中只有 {‘x’: 1} 没有 i ,
所以运行时会向外层函数(这儿是列表解析式函数 [ ])的命名空间中请求 i
而当列表解析式运行时,列表解析式命名空间中的 i 经过循环依次变化为 0–>1–>2–>3 最后固定为 3 ,
所以当 lambda x: x*i
内层函数运行时,去外层函数取 i 每次都只能取到 3。