21 def power(values):
22 print "power", values
23 for value in values:
24 print 'powering %s' % value
25 yield value
26
27 def adder(values):
28 print "adder", values
29 for value in values:
30 print 'adding to %s' % value
31 if value % 2 ==0:
32 yield value + 3
33 else:
34 yield value + 2
35
36 elements = [1, 4, 7, 9, 12, 19]
37 res = adder(power(elements))
38 print res.next()
39 print res.next()
40 print res.next()
41 print res.next()
输出:
adder <generator object power at 0x7fb6b9ee7910> <--- is this the stdout flush matter?
power [1, 4, 7, 9, 12, 19]
powering 1
adding to 1
3
powering 4
adding to 4
7
powering 7
adding to 7
9
powering 9
adding to 9
11
我正在尝试理解上面的代码。
1) 为什么 adder 在 power [1, 4, 7, 9, 12, 19] 之前打印?
2) adder 不是迭代元素而是迭代发电机,对吗?
3) 确认我对 (1) 的看法。所以加法器首先被调用然后在for value in values
对于加法器,它正在咨询发电机,因此,为打印线供电被触发,然后加法器打印线被触发?
4) 如果是这样,为什么不打印语句 power [1, 4, 7, 9, 12, 19]
与 powering <$>
一起被调用每次都打印语句?
最佳答案
power
有一个yield
返回,这使它成为一个generator
。函数本身的代码仅在next()
被调用时执行。- 正确。
adder
依赖于生成器,并且没有关于正在迭代的数据的信息。 (比如尺寸) - 再次纠正
yield
是一个特定的指令。它不会从生成器函数 (power
) 返回。相反,它提供一个值,并暂停它的执行,直到下一次调用next()
。此时,执行从循环内部的同一点恢复。
编辑
yield
停止点的说明:
def gene():
print 'first!'
yield 1
print 'second!'
yield 2
g = gene()
g.next()
# first!
# 1
g.next()
# second!
# 2
可以看到,生成器正好在yield
指令之后被中断,准备执行下一条
关于Python 生成器 : understanding the order of execution,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22411942/