Python的生成器进阶玩法
Python的生成器进阶玩法
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.yield的表达式形式
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 def foo(): 8 print("starting") 9 while True: 10 print("=======") 11 x = yield #将yield的返回值进行赋值操作,我们可以称之为生成器表达式 12 print("value:%s"% x ) 13 14 g = foo() 15 # print(g) 16 next(g) #Next方法默认是不传值的,生成器第一次传值传值必须为空(g.send(None) ), 17 # 否则就会报错(TypeError: can't send non-None value to a just-started generator),一次传None值的操作我们称之为初始化。 18 19 g.send(100) #相比next方法多了一个传值操作,即把100传给生成器g中的yield。 20 21 g.send(None) #如果传值(send)为空(None)则等同于next(g)方法。 22 23 24 25 26 #以上代码执行结果如下: 27 starting 28 ======= 29 value:100 30 ======= 31 value:None 32 =======
二.生成器初始化传值操作
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 import time 8 9 def InitializationValue(func): #定义一个装饰器对生成器进行初始化操作。 10 def wrapper(*args,**kwargs): 11 g = func(*args,**kwargs) 12 try: 13 next(g) #进行生成器传值的初始化操作,这样用户就可以第一次进行传值(因为Next方法默认是不传值的,生成器第一次传值传值必须为空(g.send(None) )) 14 except TypeError: 15 pass 16 return g 17 return wrapper 18 19 20 @InitializationValue 21 def consumer(name): 22 # print("%s 准备吃饺子啦!"% name) 23 while True: 24 dumplings = yield 25 print("饺子[%s]来了,被[%s]吃了!"% (dumplings,name)) 26 27 @InitializationValue 28 def producer(name): 29 c = consumer("yinzhengjie") 30 # print("俺要开始准备吃饺子了!") 31 for i in range(1,10): 32 time.sleep(1) 33 print("%s做的第%s个饺子"%(name,i)) 34 c.send(i) 35 producer("尹正杰") 36 37 38 39 #以上代码执行结果如下: 40 尹正杰做的第1个饺子 41 饺子[1]来了,被[yinzhengjie]吃了! 42 尹正杰做的第2个饺子 43 饺子[2]来了,被[yinzhengjie]吃了! 44 尹正杰做的第3个饺子 45 饺子[3]来了,被[yinzhengjie]吃了! 46 尹正杰做的第4个饺子 47 饺子[4]来了,被[yinzhengjie]吃了! 48 尹正杰做的第5个饺子 49 饺子[5]来了,被[yinzhengjie]吃了! 50 尹正杰做的第6个饺子 51 饺子[6]来了,被[yinzhengjie]吃了! 52 尹正杰做的第7个饺子 53 饺子[7]来了,被[yinzhengjie]吃了! 54 尹正杰做的第8个饺子 55 饺子[8]来了,被[yinzhengjie]吃了! 56 尹正杰做的第9个饺子 57 饺子[9]来了,被[yinzhengjie]吃了!
三.面向过程编程案例
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 import os 7 8 def init(func): 9 def wrapper(*args,**kwargs): 10 g = func(*args,**kwargs) 11 next(g) 12 return g 13 return wrapper 14 15 #阶段一:递归找文件的绝对路径,把路径发给阶段二 16 @init 17 def Search(Target): 18 "sercg files abapath" 19 while True: 20 StartPath = yield 21 g = os.walk(StartPath) 22 for ParDir, _, files in g: # 注意,ParDir是父目录,其中“_"是父目录下的子目录,“files”则是父目录下的所有子文件! 23 for file in files: 24 FilePath = r"%s\%s" % (ParDir, file) 25 Target.send(FilePath) 26 27 #阶段二:收到文件路径,打开文件获取文件对象吗,把文件对象发给截断三; 28 @init 29 def Opener(Target): 30 "get file obj :f = open(filepath)" 31 while True: 32 FilePath = yield 33 with open(FilePath,encoding="utf-8")as f: 34 Target.send((FilePath,f)) 35 36 #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四; 37 @init 38 def Cat(Target): 39 "read file" 40 while True: 41 FilePath,f = yield 42 for line in f: 43 res = Target.send((FilePath,line)) 44 if res: 45 break 46 #阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五; 47 @init 48 def Grep(Target,Pattern): 49 "grep function" 50 tag = False 51 while True: 52 FilePath,line = yield tag #我们用tag来标记是否找到文件名,如果找到了就为True 53 tag = False 54 if Pattern in line: 55 Target.send(FilePath) 56 tag = True 57 #阶段五:收到文件名,并打印结果; 58 @init 59 def Printer(): 60 "parint function" 61 while True: 62 Filename = yield 63 print(Filename) 64 65 Startpath = r"E:\Code\pycharm\文件存放处\python学习笔记\DAY7" 66 g = Search(Opener(Cat(Grep(Printer(),"yinzhengjie")))) 67 68 print(g) 69 70 g.send(Startpath) 71 72 73 """ 74 经过上面的程序课件yield表达式形式有以下特征: 75 面向过程的程序设计思想: 76 核心是:过程,过程就是流程 77 优点: 78 1>.思路清晰; 79 2>.复杂的问题简单化; 80 3>.流程化; 81 缺点: 82 1>.扩展性差 83 应用: 84 1>.Linux内核; 85 2>.httpd; 86 3>.git; 87 ""” 88 89 90 91 #以上代码执行结果如下: 92 <generator object Search at 0x02A02450> 93 E:\Code\pycharm\文件存放处\python学习笔记\DAY7\1.yield的表达式形式.py 94 E:\Code\pycharm\文件存放处\python学习笔记\DAY7\2.生成器初始化传值操作.py 95 E:\Code\pycharm\文件存放处\python学习笔记\DAY7\3.面向过程编程-用生成器模拟grep功能.py 96 E:\Code\pycharm\文件存放处\python学习笔记\DAY7\access.log
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。
欢迎交流学习技术交流,个人微信: "JasonYin2020"(添加时请备注来源及意图备注)
作者: 尹正杰, 博客: https://www.cnblogs.com/yinzhengjie/p/8481429.html