day13 迭代器与生成器
一、双下方法
# print([1].__add__([2]))
# print([1]+[2])
# print(dir([])) #告诉我列表拥有的所有方法
# ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10))) #求这些类型共有的方法
# print(ret) #iterable 可迭代的
# 只要是能被for循环的数据类型 就一定拥有__iter__方法
# 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(1)))
# print([].__iter__()) #迭代器
# 一个列表执行了__iter__()之后的返回值就是一个迭代器
# print(dir([]))
# print(dir([].__iter__()))
# print(set(dir([].__iter__())) - set(dir([])))
# print([1,'a','bbb'].__iter__().__length_hint__()) #元素个数
l = [1,2,3] iterator = l.__iter__() print(iterator.__next__()) print(iterator.__next__()) print(iterator.__next__()) print(iterator.__next__())
# Iterable 可迭代的 -- > __iter__ #只要含有__iter__方法的都是可迭代的
# [].__iter__() 迭代器 -- > __next__ #通过next就可以从迭代器中一个一个的取值
# 只要含有__iter__方法的都是可迭代的 —— 可迭代协议
# 迭代器协议 —— 内部含有__next__和__iter__方法的就是迭代器
# print('__iter__' in dir([])) # print('__next__' in dir([])) #[]不是迭代器 # print('__iter__' in dir( [].__iter__())) # print('__next__' in dir( [].__iter__())) #__init__不是迭代器 # from collections import Iterable # from collections import Iterator # print(isinstance([],Iterator)) # print(isinstance([],Iterable)) # class A: # # def __iter__(self):pass # def __next__(self):pass # # a = A() # print(isinstance(a,Iterator)) # print(isinstance(a,Iterable)) # l = [1,2,3,4] # for i in l.__iter__(): # print(i)
# 迭代器协议和可迭代协议
# 可以被for循环的都是可迭代的
# 可迭代的内部都有__iter__方法
# 只要是迭代器 一定可迭代
# 可迭代的.__iter__()方法就可以得到一个迭代器
# 迭代器中的__next__()方法可以一个一个的获取值
# for循环其实就是在使用迭代器
# iterator
# 可迭代对象
# 直接给你内存地址
# print([].__iter__())
# print(range(10))
# for
# 只有 是可迭代对象的时候 才能用for
# 当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代
迭代器的好处:
从容器类型中一个一个的取值,会把所有的值取到
节省内存空间
迭代器并不会再内存中再占用一大块内存
二是随着循环每次去生成一个
每次next给我一个
二、生成器
生成器就是自己写的迭代器
生成器有两种生成方式:生成器函数
生成器表达式
# 生成器函数 def generator(): print(1) return 'a' ret = generator() print(ret)
# 只要含有yield关键字的函数都是生成器函数 # yield不能和return共用且需要写在函数内 def generator(): print(1) yield 'a' #生成器函数 : 执行之后会得到一个生成器作为返回值 ret = generator() print(ret) print(ret.__next__())
yield 与 return 的区别:
return是结束一个函数,yield不会结束函数
def generator(): print(1) yield 'a' print(2) yield 'b' yield 'c' g = generator() ret = g.__next__() print(ret) ret = g.__next__() print(ret) ret = g.__next__() print(ret)
# for i in g:
# print(i)
二、监听文件输入的例子
def tail(filename): f = open(filename,encoding='utf-8') while True: line = f.readline() if line.strip(): yield line.strip() g = tail('file') for i in g: if 'python' in i: print('***',i)