基于python生成器封裝的協(xié)程類
自從python2.2提供了yield關(guān)鍵字之后,python的生成器的很大一部分用途就是可以用來構(gòu)建協(xié)同程序,能夠?qū)⒑瘮?shù)掛起返回中間值并能從上次離開的地方繼續(xù)執(zhí)行。python2.5的時(shí)候,這種生成器更加接近完全的協(xié)程,因?yàn)樘峁┝藢⒅岛彤惓鬟f回到一個(gè)繼續(xù)執(zhí)行的函數(shù)中,當(dāng)?shù)却善鞯臅r(shí)候,生成器能返回控制。
python提供的生成器設(shè)施:
- yield:能夠?qū)⒆约簰炱?,并提供一個(gè)返回值給等待方
- send:?jiǎn)酒鹨粋€(gè)被掛起的生成器,并能夠傳遞一個(gè)參數(shù),可以在生成器中拋出異常
- next:本質(zhì)上相當(dāng)于send(None),對(duì)每個(gè)生成器的第一次調(diào)用必須不能傳遞參數(shù)
- close:主動(dòng)退出一個(gè)生成器
python封裝
雖然python3提供了asyncio這樣的異步IO庫,而且也有g(shù)reenlet等其他協(xié)程庫,但目前的需求并不是實(shí)際的網(wǎng)絡(luò)IO并發(fā)操作,而是需要模擬狀態(tài)機(jī)的運(yùn)行,因此使用協(xié)程可以很方便的模擬,并加入認(rèn)為的控制,下面是封裝的一個(gè)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)
基于上述封裝,下面實(shí)現(xiàn)了一個(gè)協(xié)同的生產(chǎn)者消費(fèi)者示例:
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)
運(yùn)行結(jié)果如下:
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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳談在flask中使用jsonify和json.dumps的區(qū)別
下面小編就為大家分享一篇詳談在flask中使用jsonify和json.dumps的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03
使用llama?Index幫你訓(xùn)練pdf的示例詳解
這篇文章主要為大家介紹了使用llama?Index?幫你訓(xùn)練pdf,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
Pandas數(shù)據(jù)處理庫畫圖與文件讀取使用示例
這篇文章主要為大家介紹了Pandas數(shù)據(jù)處理庫畫圖與文件讀取使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
windows下pycharm搭建spark環(huán)境并成功運(yùn)行 附源碼
這篇文章主要介紹了windows下pycharm搭建spark環(huán)境并成功運(yùn)行 附源碼,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04
Python中2種常用數(shù)據(jù)可視化庫Bokeh和Altair使用示例詳解
本文對(duì)Python中兩個(gè)常用的數(shù)據(jù)可視化庫?Bokeh?和?Altair?進(jìn)行了比較和探討,通過對(duì)它們的特點(diǎn)、優(yōu)缺點(diǎn)以及使用示例的詳細(xì)分析,讀者可以更好地了解這兩個(gè)庫的功能和適用場(chǎng)景,從而更好地選擇合適的庫來進(jìn)行數(shù)據(jù)可視化工作,感興趣的朋友跟隨小編一起看看吧2024-04-04

