Python-迭代协议-__iter__ __next__ iter next yield

iter

  本质是for循环调用的实质,for循环通过调用这个函数返回可迭代对象生成器形式,开始迭代取值捕获StopIteration错误退出循环

  for循环首先找__iter__方法,然后再找 __getitem__方法,如果都没找到则报错,对象不是可迭代对象

__iter__

  如果是自定义类生成的对象则iter方法调用__iter__函数, 这个函数必须返回迭代器对象

next

  启动生成器。并获取生成器第一个值

__next__

  将对象变成生成器对象,也是 next方法调用对象中__next__方法

from random import randint


class BeiMenChuiXue:
    """自己实现的迭代器"""
    def __init__(self, iterable):
        self.iterable = iterable

    def __next__(self):
        for member in self.iterable:
            yield member


class DuGuJiuJiu:
    """可迭代对象"""
    def __init__(self, numbers):
        self.numbers = numbers

    def __iter__(self):
        # 通过全局函数 iter实现
        # return iter(self.numbers)

        # 交给自己实现的迭代器
        return next(BeiMenChuiXue(self.numbers))


if __name__ == '__main__':
    numbers = [randint(-10, 10) for _ in range(10)]
    print(numbers)
    du_gu_jiu_jiu = DuGuJiuJiu(numbers)
    for member in du_gu_jiu_jiu:
        print(member)

  

 北门吹雪: https://www.cnblogs.com/2bjiujiu/

yield

  yield可以跳出函数并传出一个值,也可以传递进去一个值被函数内部收到并接着执行函数,类似函数与函数之间形成通信并且可以暂停并启动函数的特性,是协程实现的最底层原理

def bei_men_chui_xue():
    hai = yield "我是 bei_men_chui_xue 函数"
    print(hai)


if __name__ == '__main__':
    bei = bei_men_chui_xue()
    message = bei.send(None)
    print(message)
    try:
        bei.send("我是 main 函数")
    except StopIteration as e:
        pass

  

经验:

  1. for循环迭代的本质还是生成器对象,然后捕获StopIteration自动退出循环

  2. 协程实现的底层原理是yield特性,既可以暂停函数并传出一个值也可以接收一个值重新启动函数的特性最具有Python语言风格

  3. 迭代结束会自动触发StopIteration,这个异常是结束信号,需要捕获这个异常

bei_men_chui_xue: https://www.cnblogs.com/2bjiujiu/

猜你喜欢

转载自www.cnblogs.com/2bjiujiu/p/9143737.html