您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關python中如何使用生成器封裝協程類,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
自從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中如何使用生成器封裝協程類”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。