Python在处理函数中的yield语句时,返回yield语句所指定的对象/值,但不会终止当前函数的执行,而是暂时中断,保留当前的执行状态/上下文,等函数再次被调用时则接着上次yield语句继续执行,如遇到yield则再次中断并保留当前的执行状态/上下文,如此循环直到函数结束或遇到return语句时才产生一个StopIteration异常后退出。 因此包含yield语句的函数不再是普通函数,而是变成了一个生成器。
使用yield语句创建的生成器函数:
def letter_range(a,z):
while ord(a)<ord(z):
yield a
a=chr(ord(a)+1)
c1=letter_range('a','z')
c2=letter_range('a','z')
print("c1="+str(c1))
print("c2="+str(c2))
c1=<generator object letter_range at 0x00000173D41CC048> c2=<generator object letter_range at 0x00000173D41CC0C0>
上面例子的输出可以看出每次直接调用letter_range函数都会返回一个独立的生成器。
f=letter_range('a','z')
print(f.__next__())
print(f.__next__())
a b
上面代码中,通过把生成器函数赋值给f,然后通过引用f来调用生成器就可以实现迭代了。
下面的代码在yield语句后面加了一个return语句,然后我们再调用生成器,结果能清晰的反映包含yield语句函数的执行路径。
def letter_range(a,z):
while ord(a)<ord(z):
yield a
return 'over'
a=chr(ord(a)+1)
f=letter_range('a','z')
print(f.__next__())
print(f.__next__())
a
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-102-33175d5529f1> in <module> 1 f=letter_range('a','z') 2 print(f.__next__()) ----> 3 print(f.__next__()) StopIteration: over
下面的例子可以看出,yield语句就相当于程序中的断点,每个yield语句中断一次。
def letter_range(a,z):
yield 'a'
yield 'b'
yield 'c'
f=letter_range('a','z')
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
a b c
--------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-104-931315ae73c1> in <module> 7 print(f.__next__()) 8 print(f.__next__()) ----> 9 print(f.__next__()) StopIteration: