一、yield
1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器
2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次值
3:函数暂停与再继续运行的状态是有yield保存
def func(count): print('start') while True: yield count count += 1 g=func(10) print(g) print(next(g)) print(next(g))
二、yield的表达式形式的应用
函数里有yield,一旦执行,那么这个函数就是个生成器
def eater(name): print('%s 说:我开动啦' % name) while True: food = yield print('%s eat %s' % (name, food)) alex_g = eater('alex') ##执行 print(alex_g)###得到生成器<generator object eater at 0x00000000022FB200> print(next(alex_g))#打印alex 说:我开动啦,返回nane,并且函数暂停在food = yield print('==============>') print(next(alex_g))#alex eat None,返回none,然后进入循环,暂定在food = yield print('==============>') print(next(alex_g))
三、用法
def eater(name): print('%s 说:我开动啦' % name) food_list = [] while True: food = yield food_list # 针对表达式的yield,分两个阶段去使用,第一,初始化,第二,给yield传值 food_list.append(food) # ['骨头','菜汤'] print('%s eat %s' % (name, food)) alex_g = eater('alex') #####第一阶段:初始化 g = next(alex_g) # 等同于alex_g.send(None) print(g) print('===========>') # 第二阶段:给yield传值 print(alex_g.send('骨头')) # 1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值 # print('===========>') print(alex_g.send('菜汤')) print(alex_g.send('狗肉包子'))
四、单线程下实现并发的效果
def eater(name): print('%s 说:我开动啦' % name) food_list = [] while True: food = yield food_list food_list.append(food) # ['骨头','菜汤'] print('%s eat %s' % (name, food)) def producer(): alex_g = eater('alex') # 第一阶段:初始化 next(alex_g)#第一阶段 # 第二阶段:给yield传值 while True:#第二阶段 food = input('>>: ').strip() if not food: continue print(alex_g.send(food)) producer()
五、解决初始化问题
########解决初始化问题 def init(func): def wrapper(*args, **kwargs): g = func(*args, **kwargs) next(g) ###解决初始化问题 return g ##返回的是初始化以后的g return wrapper @init def eater(name): print('%s 说:我开动啦' % name) food_list = [] while True: food = yield food_list food_list.append(food) # ['骨头','菜汤'] print('%s eat %s' % (name, food)) alex_g = eater('alex') #####第二阶段:给yield传值 print(alex_g.send('骨头')) # 1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值 print('===========>')