python中协程函数的实现

2020-10-15 11:25:00
六月
来源:
https://www.lanqiao.cn/courses/1278/learning/
转贴 647

生成器是由迭代器进化而来,所以生成器对象有 __iter__  和 __next__  方法,可以使用 for 循环获得值,注意这里所说的 “获得值” 指的是下文代码块里 yield 语句中 yield 关键字后面的 i 。这是在 Python 2.5 时出现的特性,在 Python 3.3 中出现 yield from 语法之前,生成器没有太大用途。但此时 yield 关键字还是实现了一些特性,且至关重要,就是生成器对象有 send 、throw 和 close 方法。这三个方法的作用分别是发送数据给生成器并赋值给 yield 语句、向生成器中抛入异常由生成器内部处理、终止生成器。这三个方法使得生成器进化成协程。

生成器(或协程)有四种存在状态:

  • GEN_CREATED 创建完成,等待执行

  • GEN_RUNNING 解释器正在执行(这个状态在下面的示例程序中无法看到)

  • GEN_SUSPENDED 在 yield 表达式处暂停

  • GEN_CLOSE 执行结束,生成器停止

可以使用 inspect.getgeneratorstate  方法查看协程的当前状态,举例如下:

In [202]: import inspect
In [203]: def generator():
     ...:     i = '激活生成器'
     ...:     while True:
     ...:         try:
     ...:             value = yield i
     ...:         except ValueError:
     ...:             print('OVER')
     ...:         i = value
     ...:

In [204]: g = generator()  # 1
In [205]: inspect.getgeneratorstate(g)  # 2
Out[205]: 'GEN_CREATED'
In [206]: next(g)  # 3
Out[206]: '激活生成器'
In [207]: inspect.getgeneratorstate(g)
Out[207]: 'GEN_SUSPENDED'
In [208]: g.send('Hello Shiyanlou')  # 4
Out[208]: 'Hello Shiyanlou'
In [209]: g.throw(ValueError)  # 5
OVER
Out[209]: 'Hello Shiyanlou'
In [210]: g.close()  # 6
In [211]: inspect.getgeneratorstate(g)
Out[211]: 'GEN_CLOSED'
In [212]:

代码说明如下:

1、创建生成器

2、查看生成器状态

3、这步操作叫做预激生成器(或协程),这是必须要做的。在生成器创建完成后,需要将其第一次运行到 yield 语句处暂停

4、暂停状态的生成器可以使用 send 方法发送数据,此方法的参数就是 yield 表达式的值,也就是 yield 表达式等号前面的 value 变量的值变成 'Hello Shiyanlou',继续向下执行完一次 while 循环,变量 i 被赋值,继续运行下一次循环,yield 表达式弹出变量 i

5、向生成器抛入异常,异常会被 try except 捕获,作进一步处理

6、close 方法终止生成器,异常不会被抛出

因为生成器的调用方也就是程序员自己可以控制生成器的启动、暂停、终止,而且可以向生成器内部传入数据,所以这种生成器又叫做协程,generator 函数既可以叫做生成器函数,也可以叫协程函数,这是生成器向协程的过渡阶段。

发表评论
评论通过审核后显示。