基于python生成器封装的协程类


Posted in Python onMarch 20, 2019

自从python2.2提供了yield关键字之后,python的生成器的很大一部分用途就是可以用来构建协同程序,能够将函数挂起返回中间值并能从上次离开的地方继续执行。python2.5的时候,这种生成器更加接近完全的协程,因为提供了将值和异常传递回到一个继续执行的函数中,当等待生成器的时候,生成器能返回控制。

python提供的生成器设施:

  • yield:能够将自己挂起,并提供一个返回值给等待方
  • send:唤起一个被挂起的生成器,并能够传递一个参数,可以在生成器中抛出异常
  • next:本质上相当于send(None),对每个生成器的第一次调用必须不能传递参数
  • close:主动退出一个生成器

python封装

虽然python3提供了asyncio这样的异步IO库,而且也有greenlet等其他协程库,但目前的需求并不是实际的网络IO并发操作,而是需要模拟状态机的运行,因此使用协程可以很方便的模拟,并加入认为的控制,下面是封装的一个python类。

class Coroutine(object):

  """ Base class of the general coroutine object """

  STATE_RUNNING = 0
  STATE_WAITING = 1
  STATE_CLOSING = 2

  def __init__(self):
    self.state = Coroutine.STATE_WAITING
    self.started = False
    self.args = None
    self.routine = self._co()

  def _co(self):
    self.ret = None
    while True:
      self.args = yield self.ret
      if not self.started:
        self.started = True
        continue
      else:
        self.state = Coroutine.STATE_RUNNING
        self.ret = self.run(self.args)
      if self.state == Coroutine.STATE_CLOSING:
        break
      self.state = Coroutine.STATE_WAITING

  def start(self):
    """ Start the generator """
    if self.routine is None:
      raise RuntimeError('NO task to start running!')
    self.started = True
    self.routine.next()

  def finish(self):
    """ Finish the execution of this routine """
    self.state = Coroutine.STATE_CLOSING
    self.routine.close()

  def run(self, args):
    """ The runing method to be executed every once time"""
    raise NotImplementedError

  def execute(self, arg_obj):
    """ Awake this routine to execute once time """
    return self.routine.send(arg_obj)

基于上述封装,下面实现了一个协同的生产者消费者示例:

class ProducerCoroutine(Coroutine):

  """ The Producer concrete coroutine """

  def __init__(self, cnsmr):
    if not isinstance(cnsmr, Coroutine):
      raise RuntimeError('Consumer is not a Coroutine object')
    self.consumer = cnsmr
    self.consumer.start()
    super(ProducerCoroutine, self).__init__()

  def run(self, args):
    print 'produce ', args
    ret = self.consumer.execute(args)
    print 'consumer return:', ret

  def __call__(self, args):
    """ Custom method for the specific logic """
    self.start()
    while len(args) > 0:
      p = args.pop()
      self.execute(p)
    self.finish()


class ConsumerCoroutine(Coroutine):

  """ The Consumer concrete coroutine """

  def __init__(self):
    super(ConsumerCoroutine, self).__init__()

  def run(self, args):
    print 'consumer get args: ', args
    return 'hahaha' + repr(args)

运行结果如下:

produce 4
consumer get args: 4
consumer return: hahaha4
produce 3
consumer get args: 3
consumer return: hahaha3
produce 2
consumer get args: 2
consumer return: hahaha2
produce 1
consumer get args: 1
consumer return: hahaha1
produce 0
consumer get args: 0
consumer return: hahaha0

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python模块之StringIO使用示例
Apr 08 Python
Python Queue模块详细介绍及实例
Dec 27 Python
Python爬取qq music中的音乐url及批量下载
Mar 23 Python
Python 40行代码实现人脸识别功能
Apr 02 Python
Python使用MD5加密算法对字符串进行加密操作示例
Mar 30 Python
用python 实现在不确定行数情况下多行输入方法
Jan 28 Python
python提取log文件内容并画出图表
Jul 08 Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 Python
详解python tkinter包获取本地绝对路径(以获取图片并展示)
Sep 04 Python
Python lxml库的简单介绍及基本使用讲解
Dec 22 Python
如何理解python接口自动化之logging日志模块
Jun 15 Python
Python中的套接字编程是什么?
Jun 21 Python
python实现栅栏加解密 支持密钥加密
Mar 20 #Python
python实现Virginia无密钥解密
Mar 20 #Python
python实现维吉尼亚加密法
Mar 20 #Python
Python multiprocess pool模块报错pickling error问题解决方法分析
Mar 20 #Python
python实现对输入的密文加密
Mar 20 #Python
python实现字符串加密成纯数字
Mar 19 #Python
python实现简单加密解密机制
Mar 19 #Python
You might like
动画 《Pokemon Sword·Shield》系列WEB动画《薄明之翼》第2话声优阵容公开!
2020/03/06 日漫
php防止sql注入示例分析和几种常见攻击正则表达式
2014/01/12 PHP
神盾加密解密教程(二)PHP 神盾解密
2014/06/08 PHP
ThinkPHP3.1基础知识快速入门
2014/06/19 PHP
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
PHP整合PayPal支付
2015/06/11 PHP
laravel框架添加数据,显示数据,返回成功值的方法
2019/10/11 PHP
jquery教程ajax请求json数据示例
2014/01/13 Javascript
最新最热最实用的15个jQuery插件汇总
2015/07/05 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
js选项卡的制作方法
2017/01/23 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
JavaScript之json_动力节点Java学院整理
2017/06/29 Javascript
js实现数组内数据的上移和下移的实例
2017/11/14 Javascript
Vue项目全局配置微信分享思路详解
2018/05/04 Javascript
JS实现马赛克图片效果完整示例
2019/04/13 Javascript
微信小程序实现的五星评价功能示例
2019/04/25 Javascript
vue.js+elementUI实现点击左右箭头切换头像功能(类似轮播图效果)
2019/09/05 Javascript
使用JS location实现搜索框历史记录功能
2019/12/23 Javascript
vue 中url 链接左边的小图标更改问题
2019/12/30 Javascript
微信小程序:报错(in promise) MiniProgramError
2020/10/30 Javascript
python之yield表达式学习
2014/09/02 Python
python中input()与raw_input()的区别分析
2016/02/27 Python
python3实现SMTP发送邮件详细教程
2018/06/19 Python
python数值基础知识浅析
2019/11/19 Python
python语言是免费还是收费的?
2020/06/15 Python
python实现感知机模型的示例
2020/09/30 Python
使用CSS3的::selection改变选中文本颜色的方法
2015/09/29 HTML / CSS
波比布朗英国官网:Bobbi Brown英国
2017/11/13 全球购物
Bose英国官方网站:美国知名音响品牌
2020/01/26 全球购物
人力资源主管岗位职责
2014/01/29 职场文书
十八大演讲稿
2014/05/22 职场文书
雨花台导游词
2015/02/06 职场文书
学校世界艾滋病日宣传活动总结
2015/05/05 职场文书
中国合伙人观后感
2015/06/02 职场文书
企业反腐倡廉心得体会
2015/08/15 职场文书