1
Fikhtengol OP 结果:
<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 |
2
wwwjfy 2015-02-27 16:22:36 +08:00
关键字:closure
|
3
Sylv 2015-02-27 16:41:58 +08:00 1
应该是 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 两个值。 |
4
013231 2015-02-27 16:53:11 +08:00 1
看看下面简化版的代码:
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 能看明白为什么嘛? 原理一样的. |
5
Lime 2015-02-27 17:13:25 +08:00 1
闭包问题。
简单来说就是gen_func1的i是地址是相同的。 楼主把gen_func1改成如下就就明白了。 def gen_func1(n): for i in range(n): callback = lambda i=i: i yield callback |
6
Lime 2015-02-27 17:21:34 +08:00
|
7
alsotang 2015-02-27 17:29:08 +08:00 1
根据楼上各位的回答,楼主还可以去看看 nonlocal 这个关键词
|