一、 什么是生成器
#只要函数内部包含有yield关键字,那么函数名()的到的结果就是生成器,并且不会执行函数内部代码
def func():
print('====>first') # 第一次next,打印该句
num=yield 1 # 将 1结果返回,并保留此刻的状态, 第二次 g.send(54) ,将至54传给num
print('====>second',num)# 第二次也打印该句
yield 2 # 将 2 返回,并保留此刻的状态
print('====>third')
yield 3
print('====>end')
g=func() #拿到一的生成器对象
print(g) #<generator object func at 0x0000000002184360>
#print(next(g)) #接收返回值
#g.send('传给yield的值') #send还有next的功能,还可接收返回值 a=g.send('asd')
二、生成器就是迭代器
g.__iter__
g.__next__
#2、所以生成器就是迭代器,因此可以这么取值
res=next(g)
print(res)
三、协程函数#yield关键字的另外一种使用形式:表达式形式的yield
def eater(name):
print('%s 准备开始吃饭啦' %name)
food_list=[]
while True:
food=yield food_list
print('%s 吃了 %s' % (name,food))
food_list.append(food)
g=eater('egon')
g.send(None) #对于表达式形式的yield,在使用时,第一次必须传None,g.send(None)等同于next(g)
g.send('蒸羊羔')
g.send('蒸鹿茸')
g.send('蒸熊掌')
g.send('烧素鸭')
g.close()
g.send('烧素鹅')
g.send('烧鹿尾')
四、练习题
1、自定义函数模拟range(1,7,2)
#题目一:
def my_range(start,stop,step=1):
while start < stop:
yield start
start+=step
#执行函数得到生成器,本质就是迭代器
obj=my_range(1,7,2) #1 3 5
print(next(obj))
print(next(obj))
print(next(obj))
print(next(obj)) #StopIteration
#应用于for循环
for i in my_range(1,7,2):
print(i)
2、编写装饰器,实现初始化协程函数的功能
def init(func):
def wrapper(*args,**kwargs):
g=func(*args,**kwargs)
next(g)
return g
return wrapper
@init
def eater(name):
print('%s 准备开始吃饭啦' %name)
food_list=[]
while True:
food=yield food_list
print('%s 吃了 %s' % (name,food))
food_list.append(food)
g=eater('egon')
g.send('蒸羊羔')
五、总结#1、把函数做成迭代器
#2、对比return,可以返回多次值,可以挂起/保存函数的运行状态