chapter16 协程

从语法上看,协程与生成器类似。但是协程中,yield通常出现在表达式的右边(例如, datum = yield)。协程可以从调用方接受数据,如.send(datum)方法。要理解协程,需要从根本上把yield视作控制流程的方式。

生成器如何进化为协程

  • 添加了.send(...), .throw(...),.close()方法。

用作协程的生成器的基本行为

协程可以处于四个状态中的一个,当前状态可以使用inspect.getgeneratorstat(...)函数确定

  • GEN_CREATED:等待开始执行
  • GEN_RUNNING:解释器正在执行
  • GEN_SUSPENDED: 在yield表达式处暂停
  • GEN_CLOSED: 执行结束
    只有当处于暂停状态时才能调用send方法。

预激协程的装饰器

如果不预激(使用next首次启动协程,到达yield处停止),协程没什么用.我们可以使用一个预激装饰器

from functools import wraps
def coroutine(func):
    @wraps(func)
    def primer(*args,**kwargs):
    gen = func(*args, **kwargs)
    next(gen)
    return gen
return primer

终止协程和异常处理

协程中未出率的异常会向上抛出,传给next函数或者send方法的调用方(即触发协程的对象)。

  • generator.throw(): 让生成器在暂停的yield表达式处抛出指定的异常,如果生成器处理了异常,代码继续向前执行到下一个yield表达式。产出的值会成为该调用方法的返回值。如果生成器中没有处理异常,向上抛出异常,传到调用方的上下文中。
  • generator.close():致使生成器在暂停的yield表达式处抛出GeneratorExit异常。

让协程返回值

协程的返回值return表达式的值会偷偷的传给调用方,赋值给StopIteration异常的一个属性。获取该属性可以从异常的value中拿到。
其实,yield from 结构跟for循环处理StopIteration异常的方式一样。解释器不仅会捕获StopIteration异常,还会把value属性的值变为yield from表达式的值。

如何使用yield from

你可能感兴趣的:(chapter16 协程)