自定义的迭代器之 生成器

生成器的定义:生成器就是一个自定义的迭代器;因为里面有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

posted @ 2021-09-20 22:11  中州韵  阅读(88)  评论(0编辑  收藏  举报