题目如下:
def mutipliers():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in mutipliers()])
结果如何?
有人会回答[0,2,4,6],有人可能题目都看不懂。
实际结果:
【6,6,6,6】
解释:
1.lambda函数虽然叫匿名函数,但是仍然是函数
2.上述的函数触发了闭包规则。
什么是闭包函数?当前函数引用到上一层函数的局部命名空间的变量时,就会触发闭包规则,而触发了闭包规则的函数就叫做闭包函数。
只有当调用闭包函数时,它才会去引用外层函数的局部变量。
所以上述函数相当于:
def mutipliers():
a =[]
for i in range(4):
res = lambda x: i * x
a.append(res)
匿名函数引用了外部函数的局部变量 i,当调用 mutipliers()时,结果是一个列表,列表中有四个匿名函数
此时还没有调用匿名函数,当调用m(2)时,匿名函数引用外层函数mutipliers的局部变量i,但是此时i已经变成了3
所以 i=3,x=2,故结果是【6,6,6,6】
如果想实现【0,2,4,6】效果,可以进行如下修改
1.将【】换成(),这样不再是列表表达式,而是生成器,用到了才生成
2.使用yield关键字
def mutipliers():
for i in range(4):
lambda x: i * x
yield lambda x:i*x
def mutipliers():
return (lambda x:i*x for i in range(4))