python-day17--生成器

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))
1
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))
2
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
3

 

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代码文件存放目录\S6\day18')
50 
51 #用户给一个路径和关键字
52 #可以从一个文件路径中找到所有包含关键字的文件
面试题3 答案

 




 

posted @ 2017-08-02 16:16  Cool·  阅读(246)  评论(0编辑  收藏  举报