Python开发者常遇到一个经典陷阱:在循环中创建函数,这些函数却返回相同结果。
这源于闭包的延迟绑定特性。内部函数引用了外部变量,但并未立即执行,而是等到调用时才去查找变量当前的值。
看这个例子:funcs = [lambda x: x + i for i in range(3)],调用 funcs0 期望返回1,实际却得到3。
因为循环结束后 i 变成了2,所有函数共享同一个 i 的引用,所以计算结果都是 x+2。
解决方案一:使用默认参数快照当前值。将定义改为 lambda x, i=i: x + i,这样 i 的当前值会被绑定为默认参数。
解决方案二:借助 functools.partial 固定参数。from functools import partial; funcs = [partial(lambda x, i: x+i, i=i) for i in range(3)]。
解决方案三:在循环内再嵌套一层函数,用参数传递当前值。def make_func(i): return lambda x: x+i; funcs = [make_func(i) for i in range(3)]。
理解延迟绑定并非缺陷,而是设计特性。它允许创建惰性计算,但循环中生成函数时需格外小心。
掌握这个知识点,能避免生产环境中难以追踪的bug。记住:闭包捕获的是变量引用,不是变量值。
检查代码时,若发现多个函数返回值异常一致,优先考虑闭包陷阱。使用默认参数或 partial 是最简洁的修复手段。