生成器扩展知识

生成器扩展知识

前面说过函数内只要有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(值)

posted @ 2017-06-19 17:26  村口王铁匠  阅读(203)  评论(0)    收藏  举报