主要内容:
小目标:掌握生成器函数
主要内容:yield关键字使用
如果看完这篇文章,你还是弄不明白yield,
你来找我,我保证不打你,我给你发100的大红包。
1. 一个需求
想要产生一个无穷的可迭代对象,每次生成一个随机数;
问题:使用while循环,存放到列表中,内存有限,不可行
2. yield关键字
生成器函数:python中带yield关键字函数,成为生成器函数
一个例子:
import random
def genRandom():
#yield关键字
yield random.randint(0,1000)
#genRandom的返回值不是None,
#genfunc是一个:generator,生成器
genfunc = genRandom()
print(type(genfunc))
#genfunc使用next调用,返回产生的随机数
r = next(genfunc)
print(r)
结果:
803
分析:genfunc为生成器对象;
3 生成器函数调用分析
加入调试信息,观察生成器函数执行过程
import random
def genRandom():
#yield关键字
r = random.randint(0,1000)
print('befor yield')
yield r
print('after yield')
genfunc = genRandom()
第一次调用:
print(next(genfunc))
结果:没有执行:print('after yield')
befor yield
726
分析:调用yield之后,返回产生随机数:314,然后停止
再次执行:
print(next(genfunc))
结果:
after yield
StopIteration Traceback (most recent call last)
分析:执行yield下一条语句,并报异常。
原因:通过异常告知调用者,生成器执行结束;
如果想要再次执行生成器,必须重新创建生成器对象。
4. 函数中添加多个yield
一个例子:
import random
def genRandom():
print('--->1')
yield random.randint(0,1000)
print('--->2')
yield random.randint(0,1000)
print('--->3')
genfunc = genRandom()
next(genfunc)
next(genfunc)
next(genfunc)
结果:最后一次调用报异常;
--->1
--->2
--->3
StopIteration:
5. 使用for循环遍历生成器
genfunc = genRandom()
for item in genfunc:
print(item)
结果:没有问题,因为for循环处理了StopIteration异常
--->1
728
--->2
192
--->3
再次调用:
for item in genfunc:
print(item)
没有任何结果,
注意:
1.生成器函数内部yield都执行完之后,不能再次使用;
2.需要重新创建新的生成器对象
6.无限的生成器函数
代码:
import random
def genRandom():
#yield关键字
while True:
r = random.randint(0,1000)
print('befor yield')
yield r
print('after yield')
genfunc = genRandom()
for i in range(10):
print(next(genfunc))
for i in range(10000):
print(next(genfunc))
结果:可以看到,可以产生无穷尽的随机数
7.yield关键字总结
1.带yield关键字的函数,返回生成器对象;
2.yield关键字保存程序运行上下文
3.生成器可以通过for或者next进行调用,注意异常处理;
4.生成器对象执行完,需要重新创建生成器对象