• python yield 和 yield from用法总结


    #例1. 简单输出斐波那契數列前 N 个数
    #缺点:该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列
    #要提高 fab 函数的可复用性,最好不要直接打印出数列,而是返回一个 List。
    def fab1(max):
        n, a, b = 0, 0, 1
        while n < max:
            print(b,end=' ')
            a, b = b, a + b
            n = n + 1
    fab1(5)  

    #例 2. 
    #缺点:该函数在运行中占用的内存会随着参数 max 的增大而增大,如果要控制内存占用,
    #最好不要用 List 来保存中间结果,而是通过 iterable 对象来迭代   
    def fab2(max): 
        n, a, b = 0, 0, 1 
        L = [] 
        while n < max: 
            L.append(b) 
            a, b = b, a + b 
            n = n + 1 
        return L

    #例3 
    #说明:带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,
    #调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!
    #在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,
    #下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,
    #于是函数继续执行,直到再次遇到 yield。
    def fab3(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            # print b
            a, b = b, a + b
            n = n + 1
    f=fab3(5)
    print("f是一个可迭代对象,并没有执行函数")
    print(f)
    print('fab3返回的是一个iterable 对象,可以用for循环获取值')
    for n in f:
        print(n)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #例4:
    #说明:yield from iterable本质上等于for item in iterable: yield item的缩写版   
     
    def f_wrapper1(f):
        for g  in f:
            yield g
    wrap = f_wrapper1(fab3(5))
    for in wrap:
        print(i,end=' ')
     
    print(' 使用yield from代替for循环')
    def f_wrapper2(f):
         yield from f#注意此处必须是一个可生成对象
    wrap = f_wrapper2(fab3(5))
    for in wrap:
        print(i,end=' ')
    print(' ---------------------')
     
     
    print('yield from包含多个子程序')
    def g(x):
        yield from range(x, 0, -1)
        yield from range(x)
    print(list(g(5)))
    for g  in g(6):
        print(g,end=',')
         
         
    print(' ---------------------')  注意红色部分就是替代的部分,yield from iterable本质上等于for item in iterable: yield item的缩写版   
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #例5 利用yield from语句向生成器(协程)传送数据
    #传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。
    #如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,换回生产者继续生产,效率极高:
    def  consumer_work(len):
        # 读取send传进的数据,并模拟进行处理数据
        print("writer:")
        w=''
        while True:
            w = yield w    # w接收send传进的数据,同时也是返回的数据
            print('[CONSUMER] Consuming %s...>> ', w)
            w*=len #将返回的数据乘以100
            time.sleep(0.1) 
    def consumer(coro):
        yield from coro#将数据传递到协程(生成器)对象中
     
     
    def produce(c):
        c.send(None)# "prime" the coroutine
        for in range(5):
            print('[Produce] Producing %s----', i)
            w=c.send(i)#发送完成后进入协程中执行
            print('[Produce] receive %s----', w)
        c.close()
         
    c1=consumer_work(100)
    produce(consumer(c1))<br><br>执行结果:<br>writer:<br>[Produce] Producing %s---- 0<br>[CONSUMER] Consuming %s...>>  0<br>[Produce] receive %s---- 0<br>[Produce] Producing %s---- 1<br>[CONSUMER] Consuming %s...>>  1<br>[Produce] receive %s---- 100<br>[Produce] Producing %s---- 2<br>[CONSUMER] Consuming %s...>>  2<br>[Produce] receive %s---- 200<br>[Produce] Producing %s---- 3<br>[CONSUMER] Consuming %s...>>  3<br>[Produce] receive %s---- 300<br>[Produce] Producing %s---- 4<br>[CONSUMER] Consuming %s...>>  4<br>[Produce] receive %s---- 400<br><br>yield from一般掌握这两种用法即可
  • 相关阅读:
    4 Apr 18 软件开发目录 logging模块的使用 序列化(Json, Pickle) os模块
    3 Apr 18 内置函数 列表生成式与生成器表达式 模块的使用之import 模块的使用之from…import…
    2 Apr 18 三元表达式 函数递归 匿名函数 内置函数
    30 Mar 18 迭代器 生成器 面向过程的编程
    29 Mar 18 函数 有参、无参装饰器
    28 Mar 18 函数
    27 Mar 18 函数的参数
    26 Mar 18 函数介绍
    23 Mar 18 文件处理
    22 Mar 18 补充数据类型+字符编码+文件处理
  • 原文地址:https://www.cnblogs.com/jfdwd/p/11260064.html
Copyright © 2020-2023  润新知