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:Codepycharm文件存放处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:Codepycharm文件存放处python学习笔记DAY71.yield的表达式形式.py
94 E:Codepycharm文件存放处python学习笔记DAY72.生成器初始化传值操作.py
95 E:Codepycharm文件存放处python学习笔记DAY73.面向过程编程-用生成器模拟grep功能.py
96 E:Codepycharm文件存放处python学习笔记DAY7access.log
原文地址:https://www.cnblogs.com/yinzhengjie/p/8481429.html