本文共 2003 字,大约阅读时间需要 6 分钟。
协程是一种非抢占式多任务调度的计算机程序组件,它允许在不同的入口点暂停或继续执行程序。这类似于一个可以被暂停的函数,或者更直观地说,是一种生成器。
协程是程序设计中一种特殊的函数,它可以暂停或恢复执行。协程允许在不同的入口点进行状态切换,从而实现多任务的非抢占式调度。
在Python中,协程是通过yield语法实现的。yield语法允许函数暂停执行,而send函数则用于向协程发送值,恢复执行。
通过inspect.getgeneratorstate()函数可以获取协程的状态:
yield表达式处暂停。当协程未处理异常时,异常会向上抛出,传递到主线程中的调用方。终止协程的常见方法是通过发送None或Ellipsis等哨兵值。
yield from语法用于简化协程的调用。生成器正常终止会抛出StopIteration异常,其值属性包含返回值。yield from语法能够捕获这个异常,并将返回值直接返回。
委派生成器是指包含yield from语法的生成器函数。它允许调用方直接将值传递给子生成器,子生成器在完成后会将结果传递回调用方。
以下是一些协程的代码示例:
def simple_coroutine(): print('-> start') x = yield print('-> received', x) yield# 使用协程sc = simple_coroutine()print(1111)sc.send(None) # 等同于 next(sc)sc.send('zhexiao') def simple_coroutine(a): print('-> start') b = yield a print('-> received', a, b) c = yield a + b print('-> received', a, b, c)# 使用协程sc = simple_coroutine(5)aa = next(sc) # 5bb = sc.send(6) # 5, 6cc = sc.send(7) # 5, 6, 7 def gen(): for c in 'AB': yield c# 使用生成器print(list(gen()))def gen_new(): yield from 'AB'print(list(gen_new()))
from collections import namedtupleResClass = namedtuple('Res', 'count average')def averager(): total = 0.0 count = 0 average = None while True: term = yield if term is None: break total += term count += 1 average = total / count return ResClass(count, average)def grouper(storages, key): while True: storages[key] = yield from averager()def client(): process_data = { 'boys_2': [39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3], 'boys_1': [1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46] } storages = {} for k, v in process_data.items(): coroutine = grouper(storages, k) next(coroutine) for dt in v: coroutine.send(dt) coroutine.send(None) print(storages)client() 这些代码示例展示了协程的基本用法及其在不同场景下的应用。
转载地址:http://srba.baihongyu.com/