• python中的迭代器&&生成器&&装饰器


    迭代器iterator

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
    迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。
    迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件

    特点
    访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
    不能随机访问集合中的某个值 ,只能从头到尾依次访问
    访问到一半时不能往回退
    便于循环比较大的数据集合,节省内存

    作用

    这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
    另外,还可通过yield实现在单线程的情况下实现并发运算的效果

    判断一个对象是否是可迭代对象

    '''
    Created on 2018年1月5日
    
    @author: cq
    '''
    from collections import Iterable
    
    class Obj(object):
        pass
    
    
    class Fab(object): 
        def __init__(self, max): 
            self.max = max 
            self.n, self.a, self.b = 0, 0, 1 
    
        def __iter__(self): 
            return self 
    
        def next(self): 
            if self.n < self.max: 
                r = self.b 
                self.a, self.b = self.b, self.a + self.b 
                self.n = self.n + 1 
                return r 
            raise StopIteration()
        
    
    def main():
        print("Python常见对象的可迭代性")
        print("abc :%s" % type('abc'))
        print("is iterable >>",isinstance('abc',Iterable),"
    ")
        print("123456 :%s" % type(123456))
        print("is iterable >>",isinstance(123456,Iterable),"
    ")
        print("[1,2,4,5,6] :%s" % type([1,2,4,5,6]))
        print("is iterable >>",isinstance([1,2,4,5,6],Iterable),"
    ")
        print("{1,2,4,5,8,5,5,5,5} :%s" % type({1,2,4,5,8,5,5,5,5}))
        print("is iterable >>",isinstance({1,2,4,5,8,5,5,5,5},Iterable),"
    ")
        print("(1,2,4,5,6,8) :%s" % type((1,2,4,5,6,8)))
        print("is iterable >>",isinstance((1,2,4,5,6,8),Iterable),"
    ")
        print("{'a':1,'b':2} :%s" % type({"a":1,"b":2}))
        print("is iterable >>",isinstance({"a":1,"b":2},Iterable),"
    ")
        print("Obj() :%s" % type(Obj()))
        print("is iterable >>",isinstance(Obj(),Iterable),"
    ")
        print("Fab(2) :%s" % type(Fab(2)))
        print("is iterable >>",isinstance(Fab(2),Iterable),"
    ")
        
        
    if __name__ == '__main__':
        main()
     1 # 输出结果如下
     2 
     3 Python常见对象的可迭代性
     4 abc :<class 'str'>
     5 is iterable >> True 
     6 
     7 123456 :<class 'int'>
     8 is iterable >> False 
     9 
    10 [1,2,4,5,6] :<class 'list'>
    11 is iterable >> True 
    12 
    13 {1,2,4,5,8,5,5,5,5} :<class 'set'>
    14 is iterable >> True 
    15 
    16 (1,2,4,5,6,8) :<class 'tuple'>
    17 is iterable >> True 
    18 
    19 {'a':1,'b':2} :<class 'dict'>
    20 is iterable >> True 
    21 
    22 Obj() :<class '__main__.Obj'>
    23 is iterable >> False 
    24 
    25 Fab(2) :<class '__main__.Fab'>
    26 is iterable >> True 

    迭代对象的next方法

    '''
    Created on 2018年1月5日
    
    @author: cq
    '''
    
    def main():
        str1 = 'hello world!'
        list1 = [1,2,3,4,5,6]
        dicts1 = {'name' : "bob", 'age' : "18", 'city' : "Paris", 'gender' : "male" }
        
        print("迭代输出可迭代对象'字符串'的元素")
        list_iter = iter(str1)
        for i in range(len(str1)):
            print(list_iter.__next__())
        print("----------------------")
        
        
        print("迭代输出可迭代对象[列表]的元素")
        list_iter = iter(list1)
        for i in range(len(list1)):
            print(list_iter.__next__())
        print("----------------------")
        
       
        print("迭代输出可迭代对象{字典}的元素")
        list_iter = iter(dicts1.keys())
        for i in range(len(dicts1)):
            print(list_iter.__next__())
        print("----------------------")
        
        print("迭代输出可迭代对象{字典}的元素")
        list_iter = iter(dicts1.values())
        for i in range(len(dicts1)):
            print(list_iter.__next__())   
        print("----------------------")
        
        print("迭代输出可迭代对象{字典}的元素")
        list_iter = iter(dicts1.items())
        try:
            while True:
                print(list_iter.__next__())
        except StopIteration:
            pass
    
    if __name__ == '__main__':
        main()
    # 输出
    
    迭代输出可迭代对象'字符串'的元素
    h
    e
    l
    l
    o
     
    w
    o
    r
    l
    d
    !
    ----------------------
    迭代输出可迭代对象[列表]的元素
    1
    2
    3
    4
    5
    6
    ----------------------
    迭代输出可迭代对象{字典}的元素
    name
    age
    city
    gender
    ----------------------
    迭代输出可迭代对象{字典}的元素
    bob
    18
    Paris
    male
    ----------------------
    迭代输出可迭代对象{字典}的元素
    ('name', 'bob')
    ('age', '18')
    ('city', 'Paris')
    ('gender', 'male')
    Result

    可迭代类的使用

    '''
    Created on 2018年1月5日
    
    @author: cq
    '''
    import time
    
    
    class EvenNumber(object):  
        def __init__(self, index=0):  
            self.index = index + 1  
              
        
        # 声明可迭代类,并返回当前对象做为可迭代对象  
        # 该方法不会在类实例化的时候调用,当该类做为迭代对象使用时,有且在当前类调用一次
        def __iter__(self):
            print("---------",self.index)
            return self  
          
        
        # 与迭代对象一样,调用next方法获取对象
        def __next__(self):
            self.index -= 1   
            if self.index < 0:  
                raise StopIteration  
            elif divmod(self.index, 2) == (self.index/2,0):   
                return self.index  
     
        
    
    def main():
        for i in EvenNumber(12):
            if i is not None:  
                print(i) 
        
        
    if __name__ == '__main__':
        main()
    # 输出结果
    # 输出小于该数的偶数
    
    --------- 13
    12
    10
    8
    6
    4
    2
    0
    Result

    生成器generator

    定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器

    '''
    Created on 2018年1月5日
    
    @author: cq
    '''
    
    import time
    
    
    # 此函数包含yield语法,是生成器 ,只能等待__next__()方法唤醒返回迭代对象
    def salaryMan(name):
        """
            
        """
        print("%s: ~~~~~太早了关闹钟继续睡
    " % name)
        while True:
            plan = yield
            print("%s: 今天的计划是 %s" % (name, plan))
            if plan == "爬山" or plan == "打球":
                print("%s: 睡个X儿,%s去" % (name, plan))
            else:
                print("%s: 不想去太困了,再睡伙
    " % name)
    
    
    def alarmClock():
        iterable2 = sleeper1.__next__()
        iterable3 = sleeper2.__next__()
        print("刚响就被关掉了,2S后在响吧...
    ")
        time.sleep(2)
        plan_list = ["打球", "爬山", "看电影", "逛街"]
        while len(plan_list):
            print("闹钟又响了~~~")
            sleeper1.send(plan_list.pop())
            sleeper2.send(plan_list.pop())
            time.sleep(1)
    
    def main():
        global sleeper1,sleeper2
        sleeper1 = salaryMan("老王")
        sleeper2 = salaryMan("老李")
        print("闹钟还有1S响...
    ")
        time.sleep(2)
        alarmClock()
    
    
    if __name__ == '__main__':
        main()
        
    # 输出结果
     
    闹钟还有1S响...
    
    老王: ~~~~~太早了关闹钟继续睡
    
    老李: ~~~~~太早了关闹钟继续睡
    
    刚响就被关掉了,2S后在响吧...
    
    闹钟又响了~~~
    老王: 今天的计划是 逛街
    老王: 不想去太困了,再睡伙
    
    老李: 今天的计划是 看电影
    老李: 不想去太困了,再睡伙
    
    闹钟又响了~~~
    老王: 今天的计划是 爬山
    老王: 睡个X儿,爬山去
    老李: 今天的计划是 打球
    老李: 睡个X儿,打球去
    Result

    扩展:基于yield生成器对象,实现异步回调

    from queue import Queue
    from functools import wraps
    
    
    def apply_async(func, args, *, callback):
        # Compute the result
        result = func(*args)
    
        # Invoke the callback with the result
        callback(result)
    
    class Async:
        def __init__(self, func, args):
            self.func = func
            self.args = args
    
    def inlined_async(func):
        @wraps(func)
        def wrapper(*args):
            f = func(*args)
            result_queue = Queue()
            result_queue.put(None)
            while True:
                result = result_queue.get()
                try:
                    ## 注意,这里不仅发送消息给生成器,并且等待生成器返回值
                    a = f.send(result)
                    apply_async(a.func, a.args, callback=result_queue.put)
                except StopIteration:
                    break
        return wrapper
    
    
    
    
    def add(x, y):
        return x + y
    
    @inlined_async
    def test():
        for n in [x for x in range(10) if x % 2 == 0]:
            r = yield Async(add, (n, n))
            print(r)
    
    if __name__ == '__main__':
        test()
    0
    4
    8
    12
    16
    Result

    装饰器decorator

    函数调用+函数嵌套+高阶函数


    函数调用:执行其他地方的函数体
    函数嵌套:就是指在某些情况下,需要将某函数作为另一函数的参数使用
    高阶函数:接受一个或多个函数作为参数,即形式参数中接收函数

    装饰器满足开闭原则
    对于扩展是开放的,对于修改是关闭的。

    功能
    当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为而不用修改源代码,避免影响原来应用的运行

    '''
    Created on 2018年1月5日
    
    @author: cq
    '''
    
    import time
    
    
    def time_cost(func):
        def wrapper(*args,**kwargs):
            sTime = time.time()
            func(*args,**kwargs)
            print("Time cost:%s"%(time.time()-sTime))
        return wrapper
    
    
    # 在不改变算法函数的同,添加计算时间开销的功能
    @time_cost
    def algorithm():
        print("算法开始执行...")
        time.sleep(2)
    
    if __name__ == '__main__':
        algorithm()
    # 输出结果
    
    算法开始执行...
    Time cost:2.0004446506500244
    Result

    参考博客:http://www.cnblogs.com/alex3714/articles/5143440.html

  • 相关阅读:
    Python对JSON的操作 day3
    Python 文件操作 day2
    Python 字符串常用方法 day2
    Python字典 day2
    Python基础学习(day1)
    Excel图表转成图片
    hadoop —— MapReduce:统计访问所有独立IP个数 、 统计网站子目录访问次数 、 统计每个IP访问的子目录数
    Java -D命令对应的代码中获取-D后面的参数 和 多个参数时-D命令的使用
    hadoop —— teragen & terasort
    C# 计时器 以“天时分秒毫秒”形式动态增加显示
  • 原文地址:https://www.cnblogs.com/cq146637/p/8206868.html
Copyright © 2020-2023  润新知