有如下函数:
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'))