# 迭代器
- 可迭代(Iterable):直接作用域for循环的变量
- 迭代器(Iterator):不但可以作用于for循环,还可以被next调用
- isinstance()后跟第二个参数,可以判断这个变量是否是可迭代的或是迭代器
- iterable和iterator可以转换
- 通过iter函数
# 生成器
- generator:一遍循环一遍计算下一个元素的机制/算法
- 需要满足三个条件:
- 1、每次调用都生产出for循环需要的下一个元素或者值
- 2、如果达到最后一个后,需要StopIteration异常
- 3、可以被next函数调用
- 如何生成一个生成器
- 直接使用
- 如果函数中包含yield,则这个函数就叫生成器
- 生成器用next函数调用,遇到yield返回
# 协成
- 历史历程
- 3.4引入协成,用yield实现
- 3.5引入协成语法
- 实现的协成比较好的包有asyncio、tornado、gevent
- 定义:协成是为非抢占式多任务产生子程序的计算机程序组件,协成允许不同入口点在不同位置暂停或开始执行程序
- 从技术角度讲,协成就是一个你可以暂停执行的函数,或者干脆把协成理解成生成器
- 实现:
- 1、yield返回
- 2、generator.send()调用或者next(generator)预激
- inspect.getgeneratorstate(...)函数确定,该函数会返回下述字符串中的一个(协成的四个状态):
- 1、GEN_CREATED:等待开始执行
- 2、GEN_RUNNING:解释器正在执行
- 3、GEN_SUSPENED:在yield表达式处暂停
- 4、GEN_CLOSED:执行结束
- next预激(prime)
- 协成终止
- 协成中未处理的异常会向上冒泡,传给next函数或send方法的调用方(即触发协成的对象)
- 终止协成的一种方式:发送某个哨符值,让协成退出。内置的None和Ellipsis等常量经常用作哨符值==
- yield from
- 调用协成为了得到返回值,协成必须正常终止
- 在生成器正常终止会发出StopIteration异常,异常对象的value属性保存返回值
- yield from从内部捕获StopIteration异常
- 委派生产器:包含yield from表达式的生成器函数
- 委派生产器在yield from表达式处暂停,调用方可以直接把数据发送给生成器
- 子生成器再把产出的值发给调用方
- 子生成器在最后,解释器会抛出StopIteration,并且把返回值附加到异常对象上
# 委派生成器 from collections import namedtuple ResClass = namedtuple('Res', 'count average') #第一个参数元祖名称,第二个参数元祖元素依次的名称 # 子生成器 def averager(): total = 0.0 count = 0 average = None while True: term = yield # None是哨符值 if term is None: break total += total count += 1 average = total / count # 返回元祖ResClass,里面的元素为数值的数量和所有数值的和 return ResClass(count, average) # 委派生成器 def grouper(storages, key): while True:
# 获取averager返回值也就是Res元祖 storages[key] = yield from averager() # 客户端代码 def client(): process_data = { 'boys_2':[1, 2, 3], 'boys_1':[9.8, 5.4, 3.2] } storages = {} for k, v in process_data.items(): print(k,"***",v) # 获得协成 coroutine = grouper(storages, k) # 预激协成 next(coroutine) # 发送数据到协成 for dt in v: coroutine.send(dt) # 终止协成 coroutine.send(None) print(storages) client()