1.本质:就是迭代器
2.生成器函数:
def func(): a=1 b=2 yield a #要返回的第一个值 yield b #要返回的第二个值
ret = func() #拿到一个生成器 print(next(ret)) #取第一个值 print(next(ret)) #取第二个值 print(next(ret)) #取第三个值 会报错 因为没有第三个值 3.
def f(): for i in range(1,10): yield '生产了%s件'%i s=f() for j in range(3): print(next(s)) # 生产了1件 # 生产了2件 # 生产了3件
4. import time
def tail(filename): with open(filename) as f: f.seek(0, 2) #从文件末尾算起 while True: line = f.readline() # 读取文件中新的文本行 if not line: time.sleep(0.1) continue yield lineprint(next(tail('tmp_file')))
5.#计算移动平均值
def init(func): #在调用被装饰生成器函数的时候首先用next激活生成器
def inner(*args,**kwargs): g = func(*args,**kwargs) next(g) return g return inner@init
def averager(): total = 0.0 count = 0 average = None while True: term = yield average total += term count += 1 average = total/count g_avg = averager()# next(g_avg) 在装饰器中执行了next方法print(g_avg.send(10))print(g_avg.send(30))print(g_avg.send(5))6.yield from 方法
def func(): # for i in 'AB': # yield i yield from 'AB' yield from [1,2,3] g = func() l = [] l.append(next(g)) l.append(next(g)) l.append(next(g)) l.append(next(g)) l.append(next(g)) print(l) #['A', 'B', 1, 2, 3]
7.生成器面试题:
def demo(): for i in range(4): yield ig=demo()g1=(i for i in g)g2=(i for i in g1)print(list(g1))print(list(g2))
def add(n,i): return n+idef test(): for i in range(4): yield ig=test()for n in [1,10]: g=(add(n,i) for i in g)print(list(g))
import osdef init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper@initdef list_files(target): while 1: dir_to_search=yield for top_dir,dir,files in os.walk(dir_to_search): for file in files: target.send(os.path.join(top_dir,file))@initdef opener(target): while 1: file=yield fn=open(file) target.send((file,fn))@initdef cat(target): while 1: file,fn=yield for line in fn: target.send((file,line))@initdef grep(pattern,target): while 1: file,line=yield if pattern in line: target.send(file)@initdef printer(): while 1: file=yield if file: print(file)g=list_files(opener(cat(grep('python',printer()))))g.send('/test1')协程应用:grep -rl /dir
8.上面2题的 思路
# g=(add(n,i) for i in (add(n,i) for i in g)) #当n=1 时,生成器未执行,只是把式子带过来了 # print(list(g))
1 # import os 2 # 3 # def init(func): #预激活生成器的一个装饰器 4 # def wrapper(*args,**kwargs): 5 # g=func(*args,**kwargs) #func是一个生成器函数,返回的g是一个生成器 6 # next(g) #预激活生成器 7 # return g #返回激活后的生成器g 8 # return wrapper 9 #10 # @init #list_files = init(list_files) == wrapper11 # def list_files(target): #target = opener_g12 # while 1:13 # dir_to_search=yield14 # for top_dir,dir,files in os.walk(dir_to_search): #os.walk (路径,文件夹,文件)15 # for file in files: #从文件列表中获取一个一个的文件16 # target.send(os.path.join(top_dir,file)) #把文件的绝对路径传给了opener_g17 # @init #opener = init(opener) == wrapper18 # def opener(target): #target = cat_g19 # while 1:20 # file=yield #拿到了一个文件的路径21 # fn=open(file,encoding='utf-8') #打开文件获取了一个文件句柄22 # target.send((file,fn)) #cat_g发送了一个文件的路径和句柄23 # @init #cat = init(cat) == wrapper24 # def cat(target): #target = grep_g25 # while 1:26 # file,fn=yield #文件路径和文件的句柄27 # for line in fn:28 # target.send((file,line)) #文件路径,文件中的一行29 # @init #grep = init(grep) == wrapper30 # def grep(pattern,target): #要搜索的关键字,printer_g31 # lst = []32 # while 1:33 # file,line=yield #文件的路径和每一行34 # if pattern in line and file not in lst: #判断关键字是否在当前行35 # lst.append(file)36 # target.send(file) #printer_g.send文件路径37 # @init #printer = init(printer) == wrapper38 # def printer():39 # while 1:40 # file=yield #获取一个文件路径41 # if file:42 # print(file) #打印文件的路径:文件里包含了要搜索的关键字43 #44 # g=list_files(opener(cat(grep('python',printer()))))45 # # g=list_files(opener(cat(grep('python',printer_g))))46 # # g=list_files(opener(cat(grep_g)))47 # # g=list_files(opener(catg)))48 # # g=list_files(opener_g)49 # g.send('D:\Python代码文件存放目录\S6\day18')50 51 #用户给一个路径和关键字52 #可以从一个文件路径中找到所有包含关键字的文件