有如下函数:
def gen():
li = [1, 2, 3, 4]
for i in li:
yield i
a = gen()
try:
while True:
print(a.next())
except StopIteration:
print('generator ({}) has finished.'.format('a'))
print(gen)
print(a)
这里,gen是个函数,而a是个生成器
所以输出:
1
2
3
4
generator (a) has finished.
<function gen at 0x7f010d70c410> #gen果然是个函数
<generator object gen at 0x7f010d748d70> #a的确是个生成器
所以针对a,就把它当作一个类的实例来处理。
而如何给生成器发信息呢?
首先,生成器得有东西接收我们发的信息吧,如下添加:
def gen():
li = [1, 2, 3, 4]
for i in li:
recvor1 = yield i
print('generator received: {}'.format(recvor1))
这样的话,给生成器发的信息会被存储到recvor1中,那么如何如何向生成器发送信息呢?
使用生成器的方法:send()
原型:
generator.send(value)
value仅仅表示说个值,你可以传递任何值,只要在生成器内部用匹配的结构接收就可以了
知道了方法,如何操作呢?
print(a.next())
print(a.send(15))
输出:
1
generator received: 15
2
由于使用生成器的时候,第一次必须调用next,所以先调用next()方法,为什么呢?
看如下生成器的路由:
用户调用next()->
开始进入gen->
创建li->
进入循环,执行第一次i的取值->
yield i 返回i,暂停生成器
用户再次执行next()->
生成器继续执行,从recvor = ...开始->
执行print语句->
第二次进入循环,为i取值->
yield i返回i,暂停生成器
用户再次执行next()->
生成器继续执行,从recvor = ...开始->
执行print语句->
第三次进入循环,为i取值->
yield i返回i,暂停生成器
直到StopIteration异常发生退出生成器
上面是个人总结。可以看出,使用send发信息,只有从第二次循环的yield才能接收数据,第一次没有人接收
来发送一个元组试试:
def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
print(a.next())
print(a.send((15, 16)))
输出:
1
generator received: (15, 16)
2
那么,如果没有发送值,而是调用了next方法,会如何呢?首先,得知道next等同于send(None)
def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
print(a.next())
print(a.next())
print(a.next())
print(a.send((15, 16)))
输出:
1
generator received: None
2
generator received: None
3
generator received: (15, 16)
4
介绍完了。还有一点要备注,对于没有正常执行完毕的生成器,即没有抛出StopIteration异常的生成器,要调用close关闭它
def gen():
li = [1, 2, 3, 4]
for i in li:
tuple1 = yield i
print('generator received: {}'.format(tuple1))
a = gen()
try:
print(a.next())
while True:
val = a.send(15)
print(val)
if val == 3:
a.close()#要关闭
break
except StopIteration:
print('generator ({}) has finished.'.format('a'))