首页 > 代码库 > day22:yield的表达形式,面向过程变成

day22:yield的表达形式,面向过程变成

一、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)运行结果:startingvalue :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@initdef 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 eatalex 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阶段一:递归地找出目录下所有文件的绝对路径,把路径发给阶段二@initdef 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)#阶段二:收到文件路径,打开文件获取文件对象,把文件对象发给阶段三@initdef opener(target):    while True:        file_path = yield        with open(file_path,encoding = ‘utf-8‘) as f:            target.send((file_path,f))#阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四@initdef cat(target):    while True:        file_path,f = yield        for line in f:            res=target.send((file_path,line))            if res:                break#阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五@initdef grep(target,pattern):    tag=False    while True:        filepath,line=yield tag        tag=False        if pattern in line:            target.send(filepath)            tag=True#阶段五:收到文件名,打印结果@initdef 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)

day22:yield的表达形式,面向过程变成