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