python匿名函数的嵌套使用循环发现的问题

在python的匿名函数的测试中发现一个问题:

def m():
    return [lambda x:x*i for i in range(4)]

a = m()
for a in m():
    print(a(1))

运行的结果我本以为会是
0
1
2
3
可是答案却是四个3,原因尚未了解。

这是Python开发者经常会出现的问题,就是对闭包作用域不清晰。在 [lambda x:x*i for i in range(4)] 列表解析式中,i在lambda声明之外,也就是说i相对lambda来说是个外部变量。当列表解析式运行完后,i的值就定格为3。

我们可以通过简单的方法来验证

for a in m():
    print(a.__code__.co_code)
    print(a(1))

你会发现,对a的内部代码输出都是一样的,这说明列表中的lambda的逻辑都是一样的。所以输出结果也是一样的。

闭包问题
i是个全局变量,而定义x*i的时候只定义了一个算法,并不直接进行计算
当你真正执行它的时候,i已经循环完了,变成最终值了,那么执行出来的当然都是同一个值