Python的闭包与延时绑定问题
今天一个在自学python的同学问了这么一个问题,感觉挺典型的,于是整理如下:
def mul(): return [lambda x : i*x for i in range(4)] print([m(2) for m in mul()]) # output: # [6, 6, 6, 6]
为毛结果是 [6, 6, 6, 6] 而不是我们以为的 [0, 2, 4, 6] 呢?
要理解这道题,我们得先弄清楚什么是闭包。
闭包定义:
1、闭包是一个嵌套函数
2、闭包必须返回嵌套函数
3、嵌套函数必须引用一个外部的非全局的局部自由变量
回到题首,这是一个闭包,为了便于理解,我们可以把代码改成:
def mul(): func_list = [] for i in range(4): def lam(x): return x*i func_list.append(lam) return func_list print([m(2) for m in mul()])
怎么理解呢?简单来说,在python里,相对而言的局部变量绑定的是值,非局部变量绑定的是空间, 而不是值本身,所以,for循环生成的i,相对于函数lam来说,是全局变量,所以绑定的是i所在的内存地址,但i最后变成了3,lam绑定的是3。
所以导致了,生成的四个函数所得值时相同的.
那么如何实现结果为 [0, 2, 4, 6] 呢? 按照刚才的思路,我们只需将lam函数中的 i 变成局部变量,这样函数lam绑定的就是值, 而不是内存地址:
def mul(): func_list = [] for i in range(4): def lam(x,i=i): return x*i func_list.append(lam) return func_list
print([m(2) for m in mul()])
这时候因为 n 是局部变量,所以绑定的是 n 的值,这样应该能理解了吧!
posted on 2019-09-21 11:10 python小菜鸡儿 阅读(84) 评论(0) 收藏 举报
浙公网安备 33010602011771号