python叠代器與生成器
阿新 • • 發佈:2017-11-06
obj root 賦值 att utf-8 get etc 不能 觸發
一、叠代
1.重復
2.下一次重復是基於上一次結果
二、叠代器
python為了提供一種不依賴於索引的叠代方式,python會為一些對象內置__iter__方法,obj.__iter__稱為可叠代的對象,obj.__iter__得到的結果就是叠代器,得到的叠代器既有__iter__,也有一個__next__方法
d={‘a‘:1,‘b‘:2,‘c‘:3} i=d.__iter__() #i叫叠代器 print(i.__next__())
三、叠代器的優缺點
1.優點:
1)提供了一種不依賴於索引的取值方式
2)惰性計算,節省內存
2.缺點
1)取值不如按照索引取值方便
2)一次性的,只能往後走不能往前推
3)無法預知長度
四、生成器
1.生成器函數:函數體內包含有yield關鍵字,該函數執行的結果是生成器函數
2.生成器就是叠代器
def foo(): print(‘first---------->‘) yield 1 print(‘second---------->‘) yield 2 print(‘third---------->‘) yield 3 print(‘fouth---------->‘) g=foo() print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__())
yield的功能:
1.與return類似,都可以返回值,但不一樣的地方在於yield返回多次值,而return只能返回一次
2.為函數封裝好了__iter__和__next__方法,吧函數的執行結果做成了叠代器
3.遵循叠代器的取值方式obj.__next__(),觸發函數的執行,函數暫停與再繼續的狀態都是由yield保存
def countdown(n): print(‘starting countdown‘) while n > 0: yield n n-=1 print(‘stop countdown‘) g=countdown(5) for i in g: print(i)
send的效果:
1.先為暫停位置的yield傳一個值,然後yield回吧值賦值給x
2.與next的功能一樣
yield的表達式形式應用
#應用:grep -rl ‘root‘ /etc import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper #階段一:遞歸地找文件的絕對路徑,把路徑發給階段二 @init def search(target): ‘search file abspath‘ while True: start_path=yield g = os.walk(start_path) for par_dir, _, files in g: # print(par_dir,files) for file in files: file_path = r‘%s\%s‘ % (par_dir, file) target.send(file_path) #階段二:收到文件路徑,打開文件獲取獲取對象,把文件對象發給階段三 @init def opener(target): ‘get file obj: f=open(filepath)‘ while True: file_path=yield with open(file_path,encoding=‘utf-8‘) as f: target.send((file_path,f)) #階段三:收到文件對象,for循環讀取文件的每一行內容,把每一行內容發給階段四 @init def cat(target): ‘read file‘ while True: filepath,f=yield for line in f: res=target.send((filepath,line)) if res: break #階段四:收到一行內容,判斷root是否在這一行中,如果在,則把文件名發給階段五 @init def grep(target,pattern): ‘grep function‘ tag=False while True: filepath,line=yield tag #target.send((filepath,line)) tag=False if pattern in line: target.send(filepath) tag=True #階段五:收到文件名,打印結果 @init def printer(): ‘print function‘ while True: filename=yield print(filename) start_path1=r‘F:\python文件\day22\a\b‘ start_path2=r‘F:\python文件\day22\a‘ g=search(opener(cat(grep(printer(),‘root‘)))) # print(g) # g.send(start_path1) g.send(start_path2)
python叠代器與生成器