一、迭代器
#双下方法:带双下划线叫双下方法 print([1].__add__([2])) print([1]+[2]) [1, 2] [1, 2]
print(dir([])) #dir这里用来展示列表拥有的所有使用方法
判断是否可迭代 print("__iter__" in dir(int)) print("__iter__" in dir(bool)) print("__iter__" in dir(list)) print("__iter__" in dir(dict)) print("__iter__" in dir(set)) print("__iter__" in dir(tuple)) print("__iter__" in dir(enumerate([]))) print("__iter__" in dir(range(2)))
只要是能被for循环的数据类型,就一定拥有__iter__方法
print([].__iter__())
一个列表执行了__iter__()之后的返回值就是一个迭代器
lis = [1, 2, 3] iterator = lis.__iter__() #把列表转换成迭代器 print(iterator.__next__()) #通过__next__方法就可以从迭代器中一个一个地取值 print(iterator.__next__()) print(iterator.__next__())
可迭代协议:只要含有__iter__方法的都是可迭代的
迭代器协议:同时含有__next__和__iter__方法的就是迭代器
from collections import Iterable from collections import Iterator print(isinstance([], Iterable)) #用isinstance方法判断[]是否可迭代 print(isinstance([], Iterator)) #用isinstance方法判断[]是否是迭代器 True False
得到一个迭代器格式 --> 可迭代的.__iter__()
迭代器中的__next__()方法可以一个一个的获取值
只有是可迭代对象的时候,才能用for循环
当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代(内部是否有__iter__方法)
迭代器的好处:
从容器类型中一个一个的取值,会把所有的值都取到
节省内存空间,迭代器并不会在内存中再占用一大块内存,而是随着循环,每次生成一个,每次__next__()获取一个值
生成器:本质还是迭代器
生成器函数:执行之后会得到一个生成器作为返回值 def generator(): print(123) yield "abc" ret = generator() print(ret) #<generator object generator at 0x0000000000B97FC0> print(ret.__next__()) 123 abc
只要含有yield关键字的函数都是生成器函数
yield不能和return共用且需要写在函数内
yield把返回值返回来,每次__next__()取一个值,并且下一个__next__()会接着取下一个值(并不是从头开始取) def ppd(): for i in range(100): yield "ppd%s号" % i ret = ppd() ret1 = ppd() print(ret.__next__()) #ppd0号 print(ret.__next__()) #ppd1号 print(ret.__next__()) #ppd2号 print(ret1.__next__()) #ppd0号 print(ret1.__next__()) #ppd1号 print(ret1.__next__()) #ppd2号
监听文件输入: def tail(filename): f = open(filename, encoding="utf-8") while True: line = f.readline() if line.strip(): yield line.strip() ret = tail("file") for i in ret: if "python" in i: print("---" + i + "---")