生成器扩展知识

生成器扩展知识

前面说过函数内只要有yield关键字,那么该函数的执行结果就是一个生成器。生成器本身也是一个迭代器对象,可以使用next()方法去取值,还有一个格式可以支持send()去传值给yield并执行next()。

def foo():
while True:
    x = yield 'aaa'
    print('value:',x)
g=foo()
print(g)
print(g.send(None))    #第一次必须要next()触发,这里使用send(None)和next(等价)
print(g.send(2))      #send传值给yield并执行next()

#执行结果:
<generator object foo at 0x000001D39EC61DB0>
aaa
value: 2
aaa

总结

  • 要使用send方法传值并触发生成器必须至少next()一次,或者send(None)一次,不然会报错:TypeError: can't send non-None value to a just-started generator

  • send(2)的作用就是先执行传值,将2传给yield,然后执行next()

加装饰器实现先next()一次生成器

def deco(func):
	def wrapper(*args,**kwargs):
		res = func(*args,**kwargs)
		next(res)
		return(res)
	return wrapper
@deco
def foo():
	print('starting ...')
	while True:
    	x = yield 'aaa'
    	print('value:', x)
g = foo()
print(g.send(2))

#执行结果
starting ...     #g = foo()执行结果
value: 2
aaa

与其它函数协同工作

def deco(func):
	def wrapper(*args,**kwargs):
		res = func(*args,**kwargs)
		next(res)
		return(res)
	return wrapper
list_eat = []
@deco
def foo(name):
	print('starting ...')
	while True:
    	food = yield list_eat   #yield接受send过来的值,传给food
    	list_eat.append(food)
    	print('%s eat %s' %(name,food))


def make_egg(people,num):
	for i in range(1,num):
    	people.send('egg%s' %i)    #发送给people,peopl必须是一个生成器

g = foo('jack')
make_egg(g,5)

#执行结果:
starting ...
jack eat egg1
jack eat egg2
jack eat egg3
jack eat egg4

多个函数通过生成器协同
两个函数间传值,接受值格式:

def deco(func):
	def wrapper(*args,**kwargs):
    	res = func(*args,**kwargs)
    	next(res)
    	return res
	return wrapper
@deco
def foo1():
	while True:
		x1 = yield    #yield接受值,可以是其它函数传值过来
		print(x1)

def foo2(target):    #target传入foo1
	target.send(值)

三个或三个以上类似:

def deco(func):
	def wrapper(*args,**kwargs):
    	res = func(*args,**kwargs)
    	next(res)
    	return res
	return wrapper
@deco
def foo1():
	while True:
		x1 = yield    #yield接受值,可以是其它函数传值过来
		print(x1)

@deco
def foo2(target):
	while True:
		x2 = yield    
		target.send(x2)
def foo3(target):
	target.send(值)
原文地址:https://www.cnblogs.com/liao-lin/p/7049692.html