• 协程


    初识协程

    '''
    协程中的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异常的第一个参数。
  • 相关阅读:
    LeetCode105 从前序遍历和中序遍历构造二叉树
    LeetCode61 扑克牌中的顺子
    LeetCode141 环形链表
    LeetCode103 二叉树的锯齿形层次遍历
    509 斐波那契数
    剑指29 顺时针打印矩阵
    malloc分配内存2种方式:brk和mmap
    Python学习第139天(Django的分页器(paginator))
    Python学习第138天(Django的用户认真组件)
    Python学习第137天(admin部分参数补充)
  • 原文地址:https://www.cnblogs.com/liuer-mihou/p/11904281.html
Copyright © 2020-2023  润新知