Python 生成器函数与 yield 语句

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: 

猜你喜欢

转载自blog.csdn.net/z54572/article/details/88991030