zoukankan      html  css  js  c++  java
  • 自定义的迭代器之 生成器

    生成器的定义:生成器就是一个自定义的迭代器;因为里面有next和iter方法

    如何得到生成器:存在yield的函数本身并不是一个生成器,需要调用才会返回一个生成器对象;不会执行内部代码,需要使用next方法

    为什么要有生成器

    首先生成器数一个自定义的迭代器,为什么要自定义,这是因为迭代器之前有个痛点,每次都是基于已存在的可迭代对象,将其转换成迭代器之后,进行取值;如果有一个需求,我要生成1000万个数字,那么如果使用了迭代器,就必须要提前创建一个存放着1000万个数字的可迭代对象,这种是很消耗内存的;因此我们就必须要自己定义一个迭代器,在迭代器内部设置好规则,后通过yield一个个返回

    def func(name):
        print('执行func方法下的第一行代码')
        n = 0
        while True:
            n += 1
            print('第%s次执行' % n)
            x = yield None
            print(f'name={name},x={x}')
    
    
    """
    函数有带有yield,那么他就是一个生成器;在执行函数时,不会执行里面的内容,而是返回生成器对象
    yield的作用:返回值,并将函数挂起
    __next__:每一次使用,会从上次yield代码所在行开始执行,直到碰到下一个yield
    """
    g = func('李白')
    
    g.__next__()  # 生成器可以直接调用__next__方法,获取下一个值
    
    """也能通过send方法给生成器进行传参,但传参必须要执行到yield代码行,因此可通过next(g)或send(None)处理"""
    x = g.send(None)
    print(x)
    g.send('send进去的值')  # 从上次挂起的位置,将值赋值给x,然后往下执行到下一个yield
    print(x)
    

    通过send方法给生成器传值

    def gen():
        s = 0
        for i in range(10):
            print('开始第', i,'次调用')
            s = yield i * s
            print('send传递进来的数据是', s)
            print()
    
    
    g = gen()
    print('第1次生成数据:', next(g))
    print('第2次生成数据:', g.send(100))
    print('第3次生成数据:', g.send(99))
    print('第4次生成数据:', g.send(98))
    
    

    关闭生成器

    使用生成器.close()

    往生成器内部发送一个异常(了解即可)

    https://blog.csdn.net/jpch89/article/details/87036970(还包含了对三种方法的总结)

    生成器惰性求值的坑

    https://blog.csdn.net/weixin_30384217/article/details/99303456

    本文来自博客园,作者:中州韵,转载请注明原文链接:https://www.cnblogs.com/zhongzhouyun/p/15315413.html

  • 相关阅读:
    图解设计模式-Visitor模式
    图解设计模式-Decorator模式
    图解设计模式-Strategy模式
    图解设计模式-Bridge模式
    HashMap源码
    LinkedList源码
    Vector源码
    ArrayList源码
    图解设计模式-Abstract Factory模式
    图解设计模式-Builder模式
  • 原文地址:https://www.cnblogs.com/zhongzhouyun/p/15315413.html
Copyright © 2011-2022 走看看