# yield把函数变成迭代器# return的返回值只返回一次,yield返回屡次# 函数在暂停以及继续下一次运行时的状态是有yield保存# 协程函数# def eater(name):# print('%s start to eat food' %name)# while True:# food=yield# print('%s get %s, to start eat' %(name,food))## print("done")## e=eater('钢蛋')# # print(e)## next(e)# e.send("包子")# e.send("饭")# print(next(e))# 用列表# def eater(name):# print('%s start to eat food' %name)# food_list=[]# while True:# food=yield food_list# print('%s get %s, to start eat' %(name,food))# food_list.append(food)## print("done")## e=eater('钢蛋')# print(next(e))# print(e.send("包子"))# print(e.send("饭"))# 课迭代的:对象下有__iter__方法的都是可迭代的对象# 迭代器:对象.__iter__()获得的结果就是迭代器# 迭代器的特性:# 迭代器.__next__()取下一个值# 优势:# 一、提供了一种统一的迭代对象的方式,不依赖于索引# 二、惰性计算# 缺点:# 一、没法获取迭代器的长度# 二、一次性的,只能日后取值,不能往前退,不能像索引那样取某个位置的值# 生成器:函数内带有yield,那么这个函数的执行结果就是生成器# 生成器本质就是迭代器# def func():# n=0# while n<5:# yield n# n+=1# g=func()# print(next(g))# print(next(g))## for i in g:# print(i)# 总结yield的功能:# 一、至关于把__iter__和__next__方法封装到函数内部# 二、与return比,return只能返回一次,而yield能返回屡次# 三、函数暂停已经继续运行的状态是经过yield保存的# yield的表达式形式:# food=yield# def eater(name):# print('%s start to eat' %name)# food_list=[]# while True:# food=yield food_list# print('%s eat %s' %(name,food))# food_list.append(food)## def aa# e=eater('zhejiangF4')# print(next(e))# e.send("大便")# e.send与next(e)的区别# 一、若是函数内yield是表达式形式,那么必须先next(e)# 二、两者的共同之处可让函数在上次暂停的位置,继续运行,不同的地方在于send在触发# 下一次代码的执行时,会顺便给yield传一个值# 我想不用加next,就能传参数# def init(func):# def wrapper(*args,**kwargs):# res=func(*args,**kwargs)# next(res)# return res # 返回 next(res),就是执行(return food_list)的下一步# return wrapper## @init #eater=init(eater)# def eater(name):# print('%s start to eat' %name)# food_list=[]# while True:# food=yield food_list # 从return res取值 food=yield food_list意思是return food_list(只执行一次)+food=yield# print('%s eat %s' %(name,food))# food_list.append(food)### e=eater('zhejiangF4') #wrapper('zhejiangF4')# # print(next(e))# e.send("大便")# e.send("小便")# 爬网页,不断地打开不一样的URL# from urllib.request import urlopen# def get():# while True:# url=yield# res=urlopen(url).read()# print(res)## g=get()# next(g) # 让光标停到url=yield# g.send('http://www/python.org') # 为了传值到URL# 协程函数## 把etc目录下,到root的文件的路径都打印出来,# 在虚拟机输入# grep -rl 'root' /etc# 就能够获得结果,可是用PYTHON,须要下面的作法# 先写流程:# def search():# '找到文件的绝对路径'# pass## def opener():# '打开文件,获取文件句柄'# pass## def cat():# '读取文件内容'# pass## def grep():# '过滤一行中有无python'# pass## def printer():# '打印包含python的路径'# pass## 在电脑运行中,输入import os# os.walk('c:\\egon'')# 或# os.walk(r'c:\egon'') # r表明右边的都是普通字符,没有转译符# g=os.walk(r'c:\egon'')# next(g)# next(g)# 咱们发现第一个值与第3个值拼接就获得文件的绝对路径# import os## def search():# while True:# dir_name=yield# g=os.walk(dir_name)# for i in g:# # print(i)# for j in i[-1]:# file_path='%s\\%s' %(i[0],j)# print(file_path)## e=search()# next(e)# e.send('c:\\egon')# 我想把包含某个字符串的文件路径找出来import os,timedef init(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) next(res) return res return wrapper@initdef search(target): '找到一个绝对路径,往下一个阶段发一个' while True: dir_name=yield # 传'c:\\egon' print("车间search开始生产产品") time.sleep(2) g=os.walk(dir_name) for i in g: for j in i[-1]: file_path='%s\\%s' %(i[0],j) target.send(file_path) # 把file_path值传到target中@initdef opener(target): '打开文件,获取文件内容' while True: # 循环地接上面程序的结果 file_path=yield # 上面的程序结果复制到file_path print('车间opener开始生产产品:文件句柄') time.sleep(2) with open(file_path) as f: target.send((file_path,f))@initdef cat(target): '读取文件内容' while True: file_path,f=yield print('车间cat开始生产产品:文件的一行内容') time.sleep(2) for line in f: target.send((file_path,line))@initdef grep(pattern,target): '过滤一行内容中有没有PYTHON' while True: file_path,line=yield print('车间grep开始生产产品:包含python这一行内容的文件路径') time.sleep(2) if pattern in line: # target.send(line) # 这是文件内容的行,不是初始要求的带有某个字符串的文件路径 target.send(file_path)@initdef printer(): '打印文件路径' while True: file_path=yield print('车间printer开始生产产品:获得最终产品') time.sleep(2) print(file_path)e=search(opener(cat(grep('python',printer()))))e.send('c:\\egon')# 以上是面向过程的编程(流水线),在设计程序时,须要把整个流程设计出来# 优势:# 一、体系结构更加清晰# 二、简化程序的复杂度# 缺点:# 可扩展性不好,一个部分改了,其余所有要改,因此设计好不会常常改,常常更新的游戏都不能用