生成器generator

发布时间 2023-06-01 11:06:21作者: limalove

1,用于协程,最近(2023/6/1)开始看到生成器用于协程这方面的内容,但还没接触,开始有所了解。

 

如果列表元素可以按照某种算法推算出来,那我们因此可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

在Python中,这种一边循环一边计算的机制,称为生成器:generator。

generator保存的是算法,每次调用next( g ),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

 创建生成器的2种方式:

1,把列表生成式中的中括号[ ] 改成小括号( )

2,生成器函数——yield关键字:如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

使用生成器:

我们创建了一个generator后,基本上永远不会调用next(),而是通过for循环来迭代它(因为如果生成器对象很多,使用next( )函数来获取每一个元素,会很麻烦),并且不需要关心StopIteration的错误。(是因为for循环内部会处理异常

对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令,for循环随之结束。

执行流程:

最难理解的就是generator和函数的执行流程不一样。

函数:是顺序执行,遇到return语句或者最后一行函数语句就返回。

generator函数:在每次调用next( )的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

生成器拿不到return语句的返回值

用for循环调用generator时拿不到return语句的返回值。

如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中。

 

 1 #定义一个生成器函数
 2 def odd():
 3     print('step 1')
 4     yield 1
 5     print('step 2')
 6     yield(3)
 7     print('step 3')
 8     yield(5)
 9     
10    
11 print("\n以下调用方式会创建多个独立的生成器:")
12 print(next(odd()))
13 print(next(odd()))
14 print(next(odd()))
15 
16 
17 print('\n正确的调用方式:')
18 g = odd()
19 print(next(g))
20 print(next(g))
21 print(next(g))
22 print(next(g))

 

调用该generator函数时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值,当迭代完再使用next()函数时会报错StopIteration。

调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。