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/