1、定義spa
1.iterator.(迭代器)code
2.iterable.(可迭代的)對象
通常來講,能夠被for循環的就是能夠迭代的,迭代器必定能夠迭代,可是可迭代的類型不必定是迭代器。blog
2、說明內存
1.有__iter__方法,說明可迭代it
def shili1(): print(dir([])) #告訴我列表擁有的全部方法 print(dir(())) print(dir('')) print(dir(range(10))) ret=set(dir([]))&set(dir(''))&set(dir({}))&set(dir(range(10))) print(ret) #有一個'__iter__'
判斷一下這些類型有沒__iter__方法io
print('__init__' in dir(int)) print('__init__' in dir(list)) print('__init__' in dir(dict)) print('__init__' in dir(set)) print('__init__' in dir(tuple)) print('__init__' in dir(enumerate)) print('__init__' in dir(range(10))) print('__iter__' in dir(int)) #false print('__iter__' in dir(bool)) #false 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(10)))
2.#setstate指定從那個位置開始取(通常是從0位開始)for循環
一個可迭代的類型執行了iter之方法後的返回值就是一個迭代器class
print(set(dir([].__iter__())) - set(dir([]))) # {'__setstate__', '__next__', '__length_hint__'}
3.示例1(可迭代的不必定是迭代器,迭代器必定可迭代)import
print('*'*40) l=[1,2,3] iterator=l.__iter__() print(iterator.__next__()) #l內部沒有next方法,調用iter以後的返回值有next print(iterator.__next__()) #l內部沒有next方法,調用iter以後的返回值有next print(iterator.__next__()) #l內部沒有next方法,調用iter以後的返回值有next # print(iterator.__next__()) #報錯 # 不能被循環的: not iterable(不可迭代的) -> __iter__ ->只要含有iter就可迭代且均可以被for循環 -> 可迭代協議
4.建立一個iterator
#[].__iter__()拿到一個 #可迭代協議 #在for循環時先找__iter__方法,若是沒有就 #迭代器協議->內部含有next方法和__init__方法的就是迭代器 print('__iter__' in dir([].__iter__())) from collections import Iterable from collections import Iterator print(isinstance([],Iterator)) #isinstace判斷是不是。迭代器,迭代類型。列表不是迭代器,可是可迭代。 print(isinstance([],Iterable)) class A: # def __init__(self):pass def __next__(self):pass #同時有next和init就是迭代器。next能夠一個一個獲取值 # def __iter__(self):pass #有iter就可用被迭代 a=A() print(isinstance(a,Iterable)) print(isinstance(a,Iterator)) #只要是迭代器必定可迭代,可迭代的不必定是迭代器 #可迭代的.__init__()方法能夠獲得一個迭代器
3、做用
使用迭代器的好處是能夠節省內存空間
#用迭代器的好處:從容器類型中一個一個的取值,會把全部值都取到 # 能夠節省內存空間(迭代器並不會再佔用一大塊內存,而是隨着循環,每次生成一個,每次next給一個 #range,文件句柄 #range-> print(range(100000000)) #range(0, 100000000) 獲得可迭代對象,但此時並無生成數據 print(list(range(10000000000000))) #內存錯誤 print(list(range(10))) #[0,1,2,……,9] #f=open -> #沒有for循環,依然能夠遍歷 l=[1,2,3,4] iterator=l.__iter__() while True: print(iterator.__next__())#雖然會報錯,可是也一個個輸出了 最後拋出StopIterator
4、總結
1.雙下方法:不多直接調用的方法,通常經過其餘語法觸發。
2.可迭代的——可迭代協議:含有__iter__的方法(‘__iter__' in dir(數據))
3.可迭代的必定能夠被for循環
4.迭代器協議:含有__iter__方法和__next__方法
5.迭代器必定可迭代,可迭代的經過調用__iter__方法能夠獲得一個迭代器
6.迭代器的特色:
1)方便使用,且只能取全部的數據取一次。下次從新取。
2)節省內存空間(當前和取下一個數據)