python 协程可以嵌套协程吗_关于Python协程(Coroutine)的理解

从语法上来看,协程和生成器类似,都是在定义体中包含yield关键字的函数

但在协程中

yield关键字通常出现在表达式的右边:

  1. 可以产出值n(y = yield n)
  2. 也可以不产出值(y = yield),或者说是产出值为None

通过next(coroutine)函数激活协程:

  1. 调用next(),返回yield右边的可有可无的值或者函数值(一般不需要next产出值,即,yield后无值,= yield),暂停

调用方是通过send(datum=None)的方式把数据提供给协程使用:

  1. send(n)函数的返回值为yield右边的值或者函数值
  2. 等号左边的变量接受send(n)函数传来的值
  • 可以理解为函数next()和函数send(n)都会执行yield右边的值或者函数值,
  • 但是send(n)函数执行完不会暂停,同时send(n)函数的参数n会赋值给等号左边的变量
def 

25574031440e643018ca572fa77d6031.png

这里的对应于send(n)的操作 y = yield 实际上是按2步进行的

  1. 第1步yield接受send(n)函数传来的参数值并赋值等号=左边的变量,即y=n
  2. 第2步执行yield后面的表达式或者函数并返回值

为了查看协程在运行过程中的四个状态,我们引入from inspect import getgeneratorstate

  1. GEN_CREATED:生成器创建完成,等待执行,可以理解为线程的就绪状态
  2. GEN_RUNNING:一般看不到,可理解为线程的执行状态
  3. GEN_SUSPENDED:在yield表达式处暂停,可理解为线程的阻塞状态
  4. GEN_CLOSED:执行结束,可理解为线程的死亡状态

a5857820bd0b11d206b4b0dd690aa6a9.png

获取协程的返回值

  1. 从异常属性中获取:协程结束时会跟生成器一样抛出StopIteration的异常,返回值就在异常对象的value属性中
  • yield from内部会自动捕获后面协程StopIteration异常,并把异常对象的value属性变成yield from的返回值
  • yield from 的主要功能就是打开双向通道,最外层的调用方调用子生成器,同时子生成器也可使用yield from调用另一个子生成器,一直嵌套调用直到遇到yield表达式结束
  • send(n)发送的值n通过yield from直接传递给了最内层的子生成器,并在yield from处等待子生成器的返回

0ccd22c73719fd3f5d83e47c581833d9.png
丛异常中获取协程返回值(1)

83704d7ff350551764357cf8ff818849.png
丛异常中获取协程返回值(2)

异步IO(asyncio)

  • Python 3.4版本引入异步IO的标准库asyncio,使用事件循环驱动协程实现并发。
  • 在asyncio库中,用asyncio.coroutine装饰用yield from来驱动协程
  • Python 3.5版本中 用async代替了asyncio.coroutine,用await代替了yield from

下面展示了Python 3.4中标准库asyncio中协程(coroutine)的应用

import threading import asyncio
@asyncio.coroutine def hello():
print('Hello world! (%s)' % threading.currentThread()) yield from asyncio.sleep(1)
print('Hello again! (%s)' % threading.currentThread())
loop = asyncio.get_event_loop()
tasks = [hello(), hello()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
asyncio​www.liaoxuefeng.com
2de0520b6675539e3875a7cb3a4af94a.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值