Python 的延迟绑定机制(大坑)
起源是看到小红书上的一个帖子:
funcs1 = []
for y in range(5):
funcs1.append(lambda x: x + y)
# Expect [5,5,5,5,5] instead of [1,2,3,4,5]
print('funcs1', [f(1) for f in funcs1])
乍看还真的蛮震惊的,感觉以前是不是写过不少此类 bug。
剧透:其实只要有现代 IDE 加持就不会写出这种 bug,各种 linter 早就打红色下划线了。
测试脚本扔在这里,大家感兴趣可以自己玩一下。
根源问题是 late binding 机制,for loop 没有自己的作用域,这点跟 javascript 是一样的。
我觉得最好的解决方法是用工厂函数,稍微紧凑些用 functools.partial
,或者在 lambda 里用默认参数。