一、迭代器
1,可以用for循环的就是迭代对象
内部含有__iter__方法的对象就叫做可迭代对象
可迭代对象就遵循可迭代协议。
可迭代对象:str,list,tuple,dict,set,range,
迭代器:f1文件句柄两种方式判断print('__iter__' in dir(s)) #dir(),查看对象的所有方法 from collections import Iterablel = [1, 2, 3, 4]print(isinstance(l, Iterable)) # True
可迭代对象转化成迭代器:可迭代对象.__iter__() --->迭代器 迭代器不仅含有__iter__,还含有__next__。遵循迭代器协议。
li=[1,2,3,4,5,6,]li_obj=li.__iter__() #迭代器
迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。 判断迭代器: print('__iter__' in dir(l1_obj)) print('__next__' in dir(l1_obj)) from collections import Iterator print(isinstance(l1_obj, Iterator)) 迭代器的好处: 1,节省内存空间。 2,满足惰性机制。 3,不能反复取值,不可逆。
for循环,能遍历一个可迭代对象,他的内部到底进行了什么?
1,将可迭代对象转化成迭代器 2,内部使用__next__一个一个取值 3,运用了异常处理去处理报错。
用while循环实现for循环 li = [1,2,3,4,5,6,7]li_obj = li.__iter__()while True: try: i = li_obj.__next__() print()i
二、生成器
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
生成器的产生方式: 1,生成器函数构造。 2,生成器推导式构造。 3,数据类型的转化。
第一:函数中只要有yield 那他就不是一个函数,而是一个生成器 第二:g称作生成器对象。
def func1(): print(111) print(222) print(333) yield 666 yield 555 yield 777g = func1()print(g) #print(g.__next__()) #111 222 333 666print(g.__next__()) #111 222 333 666 555print(g.__next__()) #111 222 333 666 555 777
常规函数定义,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间, 挂起函数的状态,以便下次重它离开的地方继续执行
def generator(): print(123) content = yield 1 print('=======',content) print(456) yield2g = generator()ret = g.__next__()print('***',ret)ret = g.send('hello') #send的效果和next一样print('***',ret)#send 获取下一个值的效果和next基本一致#只是在获取下一个值的时候,给上一yield的位置传递一个数据#使用send的注意事项 # 第一次使用生成器的时候 是用next获取下一个值 # 最后一个yield不能接受外部的值