结果: <function gen_func1 at 0x10a2b1578> first loop: 0 first loop: 1 second loop: 1 second loop: 1 <function gen_func2 at 0x10a2b15f0> first loop: 0 first loop: 1 second loop: 0 second loop: 1
wwwjfy
2015-02-27 16:22:36 +08:00
关键字:closure
Sylv
2015-02-27 16:41:58 +08:00
应该是 Namespace 命名空间的原因
方法 gen_func1 yield 出两个 callback 方法对象,因为 callback 是由 lambda 创建的,没有自己的命名空间,所以这两个 callback 对象中的变量 i 其实是同一个,都是指向 gen_func1 方法的局部变量 i。在 second loop 的时候这个变量 i 的值是 1,所以两次 print 出来的都是 1。
而方法 gen_func2 yield 出的两个 callback 方法对象,即 genf 方法对象是有自己的命名空间的,所以这两个对象的局部变量 i 不是同一个,也不是 gen_func2 的变量 i。这两个变量 i 在赋值时固定了,所以 second loop 时 print 出 0、1 两个值。
013231
2015-02-27 16:53:11 +08:00
看看下面简化版的代码:
In [42]: func1 = lambda: i
In [43]: i = 0
In [44]: func1() Out[44]: 0
In [45]: i = 3
In [46]: func1() Out[46]: 3
In [47]: gen_func2 = lambda j: lambda: j
In [48]: func2 = gen_func2(i)
In [49]: func2() Out[49]: 3
In [50]: i = 2
In [51]: func2() Out[51]: 3
能看明白为什么嘛? 原理一样的.
Lime
2015-02-27 17:13:25 +08:00
闭包问题。
简单来说就是gen_func1的i是地址是相同的。
楼主把gen_func1改成如下就就明白了。
def gen_func1(n): for i in range(n): callback = lambda i=i: i yield callback