我试图通过构建一个行为类似于“枚举”内置函数的生成器来理解 yield 语句的行为,但我目睹了不一致,具体取决于我如何迭代它。
def enumerate(sequence, start=0):
n = start
for elem in sequence:
print("Before the 'yield' statement in the generator, n = {}".format(n))
yield n, elem
n += 1
print("After the 'yield' statement in the generator, n = {}".format(n))
我对生成器的理解是,一旦到达 yield 语句,代码的执行就会停止,并返回一个值。这与我在下面的脚本中得到的相符。
a = 'foo'
b = enumerate(a)
n1,v1 = next(b)
print('n1 = {}, v1 = {}\n'.format(n1,v1))
n2,v2 = next(b)
print('n2 = {}, v2 = {}'.format(n2,v2))
在这种情况下,生成器似乎恰好在 yield 语句处停止,并在第二个“next”语句的 n+=1 中恢复:
Before the 'yield' statement in the generator, n = 0
n1 = 0, v1 = f
After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n2 = 1, v2 = o
但是,如果我使用下面的 for 循环,生成器似乎不会在 yield 语句处停止。
for n,v in enumerate(a[0:1]):
print('n = {}, v = {}'.format(n,v))
这就是我得到的:
Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1
编辑考虑评论
我意识到我只迭代了一个元素,但我没想到会看到最后一个“在生成器中的'yield'语句之后”句子(即使我迭代所有元素也会出现。
print('\n\n')
for n,v in enumerate(a):
print('n = {}, v = {}'.format(n,v))
Before the 'yield' statement in the generator, n = 0
n = 0, v = f
After the 'yield' statement in the generator, n = 1
Before the 'yield' statement in the generator, n = 1
n = 1, v = o
After the 'yield' statement in the generator, n = 2
Before the 'yield' statement in the generator, n = 2
n = 2, v = o
After the 'yield' statement in the generator, n = 3
为什么会这样?