# _*_coding:utf-8_*_ # author:leo # date: # email:[email protected] from collections import Iterable, Iterator class myIterator(): _data = None _count = 0 def __init__(self, data): self._data = data def __iter__(self): return self def __next__(self): if self._count <= len(self._data): self._count += 1 return self._data[self._count] else: raise StopIteration print(isinstance((), Iterable)) print(isinstance((), Iterator)) print(isinstance({}, Iterable)) print(isinstance({}, Iterator)) print(isinstance([], Iterable)) print(isinstance([], Iterator)) #[] {} () 均为可迭代对象 数据直接存放在栈上,有固定的内存 a = [1, 2, 3] # 定义一个列表 #print(iter(a)) #通过iter返回一个迭代器,发现是一个地址,应该是类似c/c++指针的东西,通过指针取获取内存中的值, #优点更加节省内存 #实现一个自定义的迭代器,需要实现__iter__, __next__ 方法,继承iteratable #for x in myIterator(a): #print(x) #超出下标 则抛出异常,这也是迭代器的一个特点 #还可以同过内置函数next来获取元素 iterator = iter(a) print(next(iterator)) print(next(iterator)) print(next(iterator)) #print(next(iterator)) #同样抛出同样的异常StopItereation #======================generator=========================== #b = yield 2 #报错只能用在函数中 def myGenerator(): yield 1 b = myGenerator() print(type(b)) #<class ‘generator‘> 返回生成器继承 iterator 同样要去实现__next__ #在创建的时候并不会取获取值,只有被迭代的时候调用next获取yield当前位置的下一个值 #所以说生成器一定是个迭代器,那生成器使用的场景是什么? #通常实现一个迭代器要实现对应的方法,调用yield可以生成一个可迭代的对象,貌似更加方便? 当然具体实现的细节更加复杂 #当然这只是一个优点,以后遇到在讨论。。。 for i in b: print(i) for i in b: # 只能被迭代一次,这里什么也没发生 print(i) # 在看一个稍微发杂一点的 def myGenerator2(val = None): count = 0 while count < val: yield count #这里保存当前调用的位置,再次调用则从之前记录的下一处开始 count += 1 for i in myGenerator2(10): print(i)