协程

初识协程

'''
协程中的datum=yield,其中的yild理解为控制流程的方式
'''


def simple_coroutine():
    print('-->start coroutine')
    x = yield
    print('-->continue coroutine', x)


my_coro = simple_coroutine()


# print(next(my_coro))#预激协程
# print(my_coro.send(None))


# print(my_coro.send(42))


def simple_coroutine2(a):
    print('-->start coroutine a=', a)
    b = yield a
    print('-->Received b:', b)
    c = yield a + b
    print('-->Received c:', c)


import inspect

my_coro2 = simple_coroutine2(1)
#print(inspect.getgeneratorstate(my_coro2))  # GEN_CREATED
print(my_coro2.send(None))
#print(inspect.getgeneratorstate(my_coro2))  # GEN_SUSPENDED   :在yield处暂停
print(my_coro2.send(2))
try:
    print(my_coro2.send(3))
except StopIteration as e:
    print(e.value)
#print(inspect.getgeneratorstate(my_coro2))  # GEN_CLOSED   :执行结束

# 使用协程创建一个计算平均值的功能

def average():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total+=term
        count+=1
        average=total/count



avg=average()

next(avg)

print(avg.send(1))
print(avg.send(2))
# 定义一个协程装饰器,让其预激活到第一个yield处
from functools import wraps


def corotine(func):
    @wraps(func)
    def primer(*args, **kwargs):
        gen = func(*args, **kwargs)
        next(gen)
        return gen

    return primer


@corotine
def average2():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total / count


avg = average2()
print(avg.send(1))

gen.throw的用法

class DemoException(Exception):
    '''示例'''


def demo_exc():
    print('corotione start')
    while True:
        try:
            x = yield
        except DemoException:
            print('DemoException handled Continuing...')
        else:
            print('corotinue received {!r}'.format(x))
    raise RuntimeError('This line should never run!!!')


# demo = demo_exc()
# next(demo)
# import inspect
#
# print(inspect.getgeneratorstate(demo))  # GEN_SUSPENDED 停在yield
# demo.send(1)
#
# demo.throw(DemoException)  # ====
# print(inspect.getgeneratorstate(demo))  # GEN_SUSPENDED 停在yield:说明处理完成了异常继续执行到下一个yield停止
#
# try:
#     demo.throw(StopIteration)
# except StopIteration:
#     pass
# print(inspect.getgeneratorstate(demo))  # GEN_CLOSED

  取得生成器的值:通过捕获异常的value会得到

 yield from的意义

1.子生成器的值都直接传给委派生成器的调用方
2.使用send()方法发给委派生成器的值都直接传给子生成器。
如果发送的值是None,那么会调用子生成器的的__next__()方法。
如果发送的值不是None,那么会调用子生成器的send()方法。
如果调用的方法抛出StropIteratoin异常,那么委派生成器恢复运行。
任何其他异常都会向上冒泡,传给委派生成器。
3.生成器退出是,生成器的return expr表达式会触发StrpIterration(expr)异常抛出。
4.yield from表达式的值是子生成器终止时传给StopIteration异常的第一个参数。
原文地址:https://www.cnblogs.com/liuer-mihou/p/11904281.html