1. 程式人生 > >yield的表達式形式、面向過程編程(grep -rl 'root' /etc)

yield的表達式形式、面向過程編程(grep -rl 'root' /etc)

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)