python 类的__iter__、__next__方法与yield

python迭代器

python中会使用内存的数据结构有:list、dict、set、str。
比如我们把大量数据存进了list,然后遍历这个list进行读取的话,就会占据大量内存,因此有了迭代器,用来节省空间。

那么如何创建一个python的迭代器呢?
只需要创建一个类,并实现他的__iter__()__next__()方法即可。
__iter__():是为了说明这个类是一个迭代器;
__next__():是为了在迭代过程中取数据;

举例

class Personal_Iterator:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        return self

    def __next__(self):
        print("data: ", self.data)
        if self.data == 1:
            self.data += 1
            return self.data
        self.data += 1
        return self.data


p_iter = Personal_Iterator(1)
print("p_iter", p_iter)
for i in p_iter:
    if i >= 10:
        break
    print("i: ", i)

执行结果:
在这里插入图片描述

我们可以尝试一下去掉__iter__()方法:
在这里插入图片描述

可以看到错误显示这个Personal_Iterator对象是不可迭代的,原因就是因为没实现__iter__()方法,而我们又在使用for循环尝试迭代他,因此产生了错误。

再恢复__iter__()方法,去掉__next__()方法尝试看看:
在这里插入图片描述
上面说iter()返回了一个不可迭代的类型 ‘Personal_Iterator’,iter()就是我们实现的__iter__()。为什么会报这个错呢,原因就是在for循环迭代这个对象的时候,会先调用__iter__()方法,然后返回了一个Personal_Iterator对象,之后再调用它的__next__()方法,但此时没有实现__next__()方法,因此报错。

所以总结一下就是,在用for循环遍历某个对象时,会先调用__iter__()方法,只要有这个方法,那就说明这是个可迭代对象(即迭代器),然后再调用这个迭代器的__next__()方法,去获取元素。

python生成器

由yield语句替换return语句的函数便是生成器,生成器是一种特殊的迭代器,为什么这么说呢?因为生成器也实现了__iter__()__next__()方法。

举例

def personal_generator(data):
    for i in range(5):
        data += 1
        print("data before yield: ", data)
        yield data
        print("next iterate")
        print("data after yield: ", data)

p_gen = personal_generator(0)
print("p_gen: ", p_gen)
for i in p_gen:
    print("i: ", i)

执行结果:
在这里插入图片描述
从结果上可以发现,生成器的执行流程是:

  • 用 for 循环遍历生成器
    • 第一次取出生成器生成的元素时,才会第一次执行函数里的代码,直到 yield data
    • 之后每次迭代都是从 yield 之后的代码开始执行,直到下一次 yield 为止;
    • 一直到函数内的代码全部执行完必,迭代结束;

解释一下,每次循环实际上会每次对其调用 next() 方法 ,然后生成器执行其函数内的代码,直到 yield 时停止,下一次循环再对生成器调用 next() 方法,然后生成器继续从 yield 后的代码执行,直到下一个 yield 停止。

总结

  • 迭代器
    • 实现了__iter__()__next__()方法的对象;
  • 生成器
    • 特殊的迭代器;
  • 区别
    • 一个需要手动实现__iter__()__next__()方法,而另一个只需要通过yield关键字即可生成;

参考:

  1. 如何更好地理解Python迭代器和生成器?
  2. python中yield的用法详解——最简单,最清晰的解释
  3. python之__iter__函数与__next__函数
  4. Python 迭代器 & __iter__方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值