zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一:建立MAVEN Web项目
    jvm学习笔记二(减少GC开销的建议)
    jvm学习笔记一(垃圾回收算法)
    【转】 StringUtils中 isNotEmpty 和isNotBlank的区别
    单例模式
    工厂模式
    个人项目作业
    第一次作业-热身!
    第四单元总结
    第三单元总结
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/8481429.html
Copyright © 2011-2022 走看看