zoukankan      html  css  js  c++  java
  • Python 中的协程 (2) yield from

    1 yiled from 的定义

      从字面看是yield的升级改进版本,如果将 yield 理解成返回,那么 yield from 就是从哪里返回。

    def generator2():
        yield 'a'
        yield 'b'
        yield 'c'
        yield from [11,22,33,44]
        yield from (12,23,34)
        yield from range(3)
    
    for i in generator2():
        print(i,end=' , ')
    # a , b , c , 11 , 22 , 33 , 44 , 12 , 23 , 34 , 0 , 1 , 2 , 

    yield from 返回另一个生成器。而yield 只返回一个元素。有下面的等价关系:

    yield from iterable == for item in iterable: yield item。

     

    2 yield from 的高级应用

      使用for 循环迭代生成器时,不会显式的触发StopIteration异常,因为 for 循环的底层处理了这个异常,因此也就不会得到return 的返回值。

      

    def my_generator():
        for i in range(5):
            if i==2:
                return '我被迫中断了'
            else:
                yield i
    
    def main(generator):
        try:
            for i in generator:  #不会显式触发异常,故而无法获取到return的值
                print(i)
        except StopIteration as exc:
            print(exc.value)
    
    g=my_generator()  #调用
    main(g)
    
    # 0  1

    如果使用 next 来迭代会显示的触发异常,虽然能够获取return 的返回值,但是操作麻烦。

    而使用 yield from 来实现这个需求:

    def my_generator():         # 子生成器
        for i in range(5):
            if i==2:
                return '我被迫中断了'
            else:
                yield i
    
    def wrap_my_generator(generator):  # 委托生成器
        result=yield from generator
        #自动触发StopIteration异常,并且将return的返回值赋值给yield from表达式的结果,即result
        print('这是return 的返回值,',result)
    
    def main(generator):        # 调用方
        for j in generator:
            print(j)
    
    g=my_generator()
    wrap_g=wrap_my_generator(g)
    main(wrap_g)  #调用
    '''运行结果为:
    0
    1
    这是return 的返回值, 我被迫中断了
    '''
    yield from 的特点:
    1. 上面的my_generator是原始的生成器即子生成器,main是调用方,wrap_my_generator是委托生成器

    2. 在使用yield from的时候,多了一个 委托生成器,调用方通过委托生成器来与子生成器进行交互。

    3. 委托生成器会为调用方和子生成器建立双向通道,即调用方可以和子生成器直接进行交互,委托生成器不参与代码的处理,只负责充当管道的作用以及接收 return 的返回值。

    4. yield from iteration结构会在内部自动捕获 iteration生成器的StopIteration 异常,把return返回的值或者是StopIteration的value 属性的值变成 yield from 表达式的值。

    yield from主要设计用来向子生成器委派操作任务,但yield from可以向任意的可迭代对象委派操作。

    委派生成器(group)相当于管道。可以把任意数量的委派生成器线形连接在一起。

  • 相关阅读:
    树链剖分学习笔记(未完)
    VI 配置文件(略全)
    linux之awk
    指针之基础篇
    linux之sed
    sqlplus命令手册
    Leetcode复习: 堆和栈
    leetcode 的shell部分4道题整理
    Regular Expression Matching [leetcode]
    深入浅出JAVA
  • 原文地址:https://www.cnblogs.com/wang-kai-1994/p/10375202.html
Copyright © 2011-2022 走看看