yield的表達式形式、面向過程編程(grep -rl 'root' /etc)
阿新 • • 發佈:2017-06-20
pycha app spa 絕對路徑 文件的 printer earch 判斷 裝飾器
一、yield的表達形式
def foo(): print(‘starting‘) while True: x=yield None#return 2 print(‘value :‘,x) g=foo() print(next(g)) print(g.send(2)) 運行結果: starting #運行函數,打印starting後碰到yield停住 None #next()觸發後 yield將None賦值給x,打印None後循環碰到yield停住 value : 2 #g.send(2)將2賦值給yield,yield將2賦值給x,繼續循環打印出2碰到yield停住 None #碰到yield停住並返回None,print的結果就是None
以上將yield接受到的值賦值給了x,這樣形式就叫做yield的表達式形式。
函數foo中有yield,那它就是叠代器。可以使用next()。yield可以返回結果,默認為None。
g.send()前生成器必須先next一次才能發送值。所以寫一個裝飾器,讓foo自動next一次。
def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init #foo=init(foo) def foo(): print(‘starting‘) while True: x=yield print(‘value :‘,x) g=foo() #wrapper() g.send(2) 運行結果: starting value :2
send的效果:
1:先從為暫停位置的那個yield傳一個值,然後yield會把值賦值x
2:與next的功能一樣
# _*_ coding:utf-8 _*_ def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def eater(name): print(‘%s ready to eat‘%name) food_list=[] while True: food=yield food_list food_list.append(food) print(‘%s start to eat %s‘%(name,food)) e=eater(‘alex‘) print(e.send(‘food1‘)) print(e.send(‘food2‘)) print(e.send(‘food3‘)) 運行結果: alex ready to eat alex start to eat food1 [‘food1‘] alex start to eat food2 [‘food1‘, ‘food2‘] alex start to eat food3 [‘food1‘, ‘food2‘, ‘food3‘]
二、面向過程編程
應用:grep -rl ‘root‘ /etc
實現打印出/etc目錄下所有包含‘root’的文件的文件路徑
分析完成功能的階段:
階段一:遞歸地找出目錄下所有文件的絕對路徑,把路徑發給階段二
階段二:收到文件路徑,打開文件獲取文件對象,把文件對象發給階段三
階段三:收到文件對象,for循環讀取文件的每一行內容,把每一行內容發給階段四
階段四:收到一行內容,判斷root是否在這一行中,如果在,則把文件名發給階段五
階段五:收到文件名,打印結果
import os #裝飾器,自動next() def init(func): def wrapper(*args,**kwargs): g = func(*args,**kwargs) next(g) return g return wrapper #j階段一:遞歸地找出目錄下所有文件的絕對路徑,把路徑發給階段二 @init def search(target): ‘search file abspath‘ while True: start_path=yield g = os.walk(start_path) for par_dir,_,files in g: for file in files: file_path = r‘%s\%s‘ %(par_dir,file) target.send(file_path) #階段二:收到文件路徑,打開文件獲取文件對象,把文件對象發給階段三 @init def opener(target): while True: file_path = yield with open(file_path,encoding = ‘utf-8‘) as f: target.send((file_path,f)) #階段三:收到文件對象,for循環讀取文件的每一行內容,把每一行內容發給階段四 @init def cat(target): while True: file_path,f = yield for line in f: res=target.send((file_path,line)) if res: break #階段四:收到一行內容,判斷root是否在這一行中,如果在,則把文件名發給階段五 @init def grep(target,pattern): tag=False while True: filepath,line=yield tag tag=False if pattern in line: target.send(filepath) tag=True #階段五:收到文件名,打印結果 @init def printer(): while True: filename = yield print(filename) start_path = r‘E:\PycharmProjects\qz5\day9‘ # search(opener(cat(grep(printer(),‘Jack‘))),start_path) g=search(opener(cat(grep(printer(),‘Jack‘)))) g.send(start_path)
yield的表達式形式、面向過程編程(grep -rl 'root' /etc)