funcs = []
result_list = []
for x in range(3):
def do_some():
return x
funcs.append(do_some)
result_list.append(do_some()) # 注意这里函数被执行了
funcs_result_list = [func() for func in funcs]
很多人以为result_list和funcs_result_list的结果是一样的,都是[0, 1, 2],实际结果却大跌眼镜
print(result_list ) # [0, 1, 2]
print(funcs_result_list ) # [2, 2, 2]
为什么两者的结果不一样?
-
在闭包中,
funcs.append(do_some)do_some函数并没有立即执行,而是以某种方式保存了下来, 即只返回函数的地址 -
在闭包作用域,Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询得到的
-
当执行
[func() for func in funcs], 内部函数do_some才真正被执行, 然而此时for循环已经被执行完毕,x的值不会再改变,都是2
如何改动代码,达到预期结果呢?
将循环变量作为命名变量传递给函数do_some即可
funcs = []
for x in range(3):
def do_some(x=x):
return x
funcs.append(do_some)
funcs_result_list = [func() for func in funcs]
print(funcs_result_list ) # [0, 1, 2]
为什么这样可行? 因为这会在函数内再次定义一个局部变量,不再依赖于for 循环中的x
本文深入探讨Python中闭包的概念,解析闭包中循环变量的引用陷阱,以及如何正确处理循环变量以达到预期结果。
1644

被折叠的 条评论
为什么被折叠?



