tom start to eat food
tom get 包子 ,to start eat
['包子']
tom get 骨头 ,to start eat
['包子', '骨头']
tom get 菜汤 ,to start eat
['包子', '骨头', '菜汤']
需要注意的是每次都需要先运行next()函数,让程序停留在yield位置。
如果有多个这样的函数都需要执行next()函数,让程序停留在yield位置。为了防止忘记初始化next操作,需要用到装饰器来解决此问题。
Tom start to eat food
请给Tom投喂食物:骨头
Tom get 骨头 ,to start eat
请给Tom投喂食物:菜汤
Tom get 菜汤 ,to start eat
请给Tom投喂食物:q
投喂结束
2.4 协程函数的应用
实现linux中"grep -rl error <目录>"命令,过滤一个文件下的子文件、字文件夹的内容中的相应的内容的功能程序。
首先了解一个OS模块中的walk方法,能够把参数中的路径下的文件夹打开并返回一个元组。
>>> import os # 导入模块
>>> os.walk(r"E:Pythonscript") #使用r 是让字符串中的符号没有特殊意义,针对的是转义
<generator object walk at 0x00000000035D3F10>
>>> g = os.walk(r"E:Pythonscript")
>>> next(g)
('E:\Python\script', ['.idea', '函数'], [])
返回的是一个元组,第一个元素是文件的路径,第二个是文件夹,第三个是该路径下的文件。
这里需要用到一个写程序的思想:面向过程编程。
import os
dir_g = os.walk(r"E:Pythonscript函数 est")
for dir_path in dir_g:
for file in dir_path[2]:
file = "%s\%s" %(dir_path[0],file)
print(file)
执行结果:
import os
def search():
while True:
dir_name = yield
dir_g = os.walk(dir_name)
for dir_path in dir_g:
for file in dir_path[2]:
file = "%s\%s" %(dir_path[0],file)
print(file)
g = search()
next(g)
g.send(r"E:Pythonscript函数 est")
为了把结果返回给下一流程
@init # 初始化生成器
def search(target):
while True:
dir_name = yield
dir_g = os.walk(dir_name)
for pardir,_,files in dir_g:
for file in files:
abspath = r"%s%s" %(pardir,file)
target.send(abspath)
第二阶段:打开文件
@init
def opener(target):
while True:
abspath=yield
with open(abspath,'rb') as f:
target.send((abspath,f))
第三阶段:循环读出每一行内容
@init
def cat(target):
while True:
abspath,f=yield #(abspath,f)
for line in f:
res=target.send((abspath,line))
if res:break
第四阶段:过滤
@init
def grep(pattern,target):
tag=False
while True:
abspath,line=yield tag
tag=False
if pattern in line:
target.send(abspath)
tag=True
第五阶段:打印该行属于的文件名
@init
def printer():
while True:
abspath=yield
print(abspath)
g = search(opener(cat(grep('error'.encode('utf-8'), printer()))))
g.send(r'E:Pythonscript函数 est')
执行结果: