zoukankan      html  css  js  c++  java
  • python 迭代器、生成器、装饰器

    一,迭代器

    迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器只能往前不会后退.

    特点:

    1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容

    2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问

    3. 访问到一半时不能往回退

    4. 便于循环比较大的数据集合,节省内存

    迭代器提供两种方法:

    (1)__iter__()返回迭代器对象本身

    a = iter([1,2,3,4,5])
    print(a)
    # <list_iterator object at 0x101402630>
    print(a.__next__())#输出 1
    
    print(a.__next__())#输出 2
    
    print(a.__next__())# 输出3
    
    print(a.__next__())# 输出4
    
    print(a.__next__())# 输出5
    
    print(a.__next__()) #超过后就会报错

    (2)__next__()返回迭代器的下一个元素

    names = iter(['liu', 'yao', 'sb'])
     
    print(names)
    
    print(names.__next__())
    
    print(names.__next__())
    
    print('暂停')
    
    print(names.__next__())
    
    输出:
    <list_iterator object at 0x0000000001199898>
    liu
    yao
    暂停
    sb

     (3)for...in..方法

    for使用了列表支持迭代器的性质,可以每次通过调用迭代器的next()方法,来遍历到列表中的值,直到遇到StopIteration的异常

    li = [1, 2, 3, 4]
    
    for i in li:
        print(i)

     二,生成器

    定义:

      一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);

      如果函数中包含yield语法,那这个函数就会变成生成器

      它基于yield指令,允许停止函数并立即返回结果

    特点:

      在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行

    def xrange():  #带yield为生成器函数
        print(11)
        yield 1
    
        print(22)
        yield 2
    
        print(33)
        yield 3
    
    r = xrange() #仅获取到第一个生成器
    #生成器的__next__方法
    ret = r.__next__() #获取第一次
    print(ret)
    
    ret = r.__next__()#记住上次执行的,进行寻找下一个yield,再进行执行。
    print(ret)
    
    ret = r.__next__()#获取第三次,如果上面没有yield可执行就报错,
    print(ret)

     示例

    def xrangs(n):
        start = 0
        while True:
            if start > n:
                return
            yield start
            start += 1
    
    obj = xrangs(5)
    n1 = obj.__next__()
    n2 = obj.__next__()
    n3 = obj.__next__()
    n4 = obj.__next__()
    n5 = obj.__next__()
    n6 = obj.__next__()
    print(n1,n2,n3,n4,n5,n6)
    
    输出:
    0 1 2 3 4 5

     三,装饰器

    装饰器就是把函数的名字传入进去, 在执行函数之前, 进行一些提前的处理.

    装饰器本身就是一个函数, 将所装饰的函数, 作为一个参数传进来, 

    然后在执行这个函数之前, 进行一个处理,这就是装饰器. 所以和正常函数执行顺序是一样的..

    例:如果一个公司有运维部,开发部,测试部,设计部,等,并且公司具有基础平台架构,为公司各个部门提供数据库调用,资料查看,监控等。

    当这些部门想使用这些功能的时候,直接调用这些功能的接口就可以,如下:

    ######基础平台提供的功能------------
     
    def 功能1()
     
        print ('功能1')
     
    def 功能2()
     
        print ('功能2')
     
    def 功能3()
     
        print ('功能3')
     
    def 功能4()
     
        print ('功能4')

     当运维部门调用的时候如下:

    def 功能1()
     
    def 功能2()
     
    def 功能3()

     当开发部门调用的时候如下:

    def 功能1()
     
    def 功能2()
     
    def 功能3()

    之后要为平台提供的所有功能添加验证机制,

    基础平台提供如下功能接口:

      1.让各个部门修改自己的代码

      2.在每个部门实现的功能上加上代码

      3.把验证代码变成函数 在每个功能上加入

      4.为了追寻开放封闭原则

    利用装饰器的功能实现

    def login(func):
     
        def inner():
     
            # 验证1
     
            # 验证2
     
            # 验证3
     
            return func()
     
        return inner
     
    @login
     
    def 功能1():
     
        print '功能1'
     
    @login
     
    def 功能2():
     
        print '功能2'
     
    @login
     
    def 功能3():
     
        print '功能3'
     
    @login
     
    def 功能4():
     
        print '功能4'

    当各个部门执行 def 功能的时候

    def login(func):
     
        def inner():
     
            # 验证1
     
            return func()
     
        return inner
     
    @login
     
    def 功能1():
     
        print '功能1'

    当调用功能1的时候 会先把功能1的函数名带入内存地址,之后会执行login函数,func为功能1,

    之后inner会将功能1的参数带入等待执行inner的验证功能后,

    会将参数交给func执行功能1的命令。

    实例:

    1)一个装饰器

    #有参数的装饰器
    def outer(func):
        def inner(a1,a2):
            print("1234")
            # ret = func(a1,a2)
            print("456")
            ret = func(a1,a2) #执行index函数
            return ret
        return inner
    
    
    @outer
    def index(a1,a2):
        print("非常复杂")
        return a1 + a2
    
    #只要函数应用装饰器,那么函数就被重新定义,重新定义为:装饰器的内层函数
    index(1,2)

    2)万能的装饰器

    #万能的装饰器
    
      
    def outer(func):
        def inner(*arg,**kwargs):
            print("1234")
            # ret = func(a1,a2)
            print("456")
            ret = func(*arg,**kwargs) #执行index函数
            return ret
        return inner
    
    
    @outer
    # @outer
    # 1、执行outer函数,将index作为参数传递
    # 2、将outer的返回值,重新赋值给index
    
    def index(a1,a2):
        print("非常复杂")
        return a1 + a2
    
    #只要函数应用装饰器,那么函数就被重新定义,重新定义为:装饰器的内层函数
    index(1,2,)

    3)多个装饰器

    #两个装饰器
        
        
    def outer_0(func):
        def inner(*arg,**kwargs):
            print("3.5")
            ret = func(*arg,**kwargs)
            return ret
        return inner
    
    def outer(func):
        def inner(*arg,**kwargs):
            print("1234")
            # ret = func(a1,a2)
            print("456")
            ret = func(*arg,**kwargs) #执行index函数
            return ret
        return inner
    
    @outer_0
    @outer
    def index(a1,a2):
        print("非常复杂")
        return a1 + a2
    
    #只要函数应用装饰器,那么函数就被重新定义,重新定义为:装饰器的内层函数
    index(1,2,)
    
    @outer
    def f1(a1,a2,a3):
        print("f1")
        return f1
    
    f1(6,7,8)

  • 相关阅读:
    转--- 一些概念不错的理解
    python 生产者 --- 消费者
    python GUI 之 tkinter
    读DataSnap源代码(二)
    读DataSnap源代码(一)
    FireDAC探索 (二)
    FireDAC内部初探
    C++Builder XE7 中“匿名”方法实现
    DelphiXE7 Datasnap TDSClientCallbackChannelManager内部实现初探
    C++ Builder使用VC DLL
  • 原文地址:https://www.cnblogs.com/kongqi816-boke/p/5607634.html
Copyright © 2011-2022 走看看