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 line
print(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 i g=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+i def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) print(list(g))

import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def 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)) @init def opener(target): while 1: file=yield fn=open(file) target.send((file,fn)) @init def cat(target): while 1: file,fn=yield for line in fn: target.send((file,line)) @init def grep(pattern,target): while 1: file,line=yield if pattern in line: target.send(file) @init def 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) == wrapper 11 # def list_files(target): #target = opener_g 12 # while 1: 13 # dir_to_search=yield 14 # 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_g 17 # @init #opener = init(opener) == wrapper 18 # def opener(target): #target = cat_g 19 # while 1: 20 # file=yield #拿到了一个文件的路径 21 # fn=open(file,encoding='utf-8') #打开文件获取了一个文件句柄 22 # target.send((file,fn)) #cat_g发送了一个文件的路径和句柄 23 # @init #cat = init(cat) == wrapper 24 # def cat(target): #target = grep_g 25 # while 1: 26 # file,fn=yield #文件路径和文件的句柄 27 # for line in fn: 28 # target.send((file,line)) #文件路径,文件中的一行 29 # @init #grep = init(grep) == wrapper 30 # def grep(pattern,target): #要搜索的关键字,printer_g 31 # 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) == wrapper 38 # 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代码文件存放目录S6day18') 50 51 #用户给一个路径和关键字 52 #可以从一个文件路径中找到所有包含关键字的文件