• Python 迭代器与生成器及装饰器


    1.迭代器(Iterator)

    迭代器是访问集合元素的一种方式。有下面特点:

    1)每次调用__next__()方法只访问一个元素,而且不能后退,便于循环比较大的数据集合,节省内存;(当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器)

    2)只能从头到尾访问,不能随机访问某个值;

    3)迭代器提供了一个统一的访问集合的接口,只要定义了iter()方法对象,就可以使用迭代器访问。

    迭代器使用:

    lis=['a','b','c','d']
    a=iter(lis)
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())
    print(a.__next__())    #没有元素获取,导致StopIteration报错
    
    #运行结果
    a
    b
    c
    d
    Traceback (most recent call last):
      File "F:/Python/pythoncode/s12/study/study5.py", line 318, in <module>
        print(a.__next__())
    StopIteration

    使用for循环访问迭代器:

    lis=['a','b','c','d']
    a=iter(lis)
    for st in a:
        print(st)
    
    #运行结果
    a
    b
    c
    d


    2.生成器(Generator)

    一个调用返回迭代器的函数,就叫做生成器。函数中包含yield语法,这个函数就会变成生成器。

     1)生成器表达式

    用来生成有规律的生成器

    格式:generator_name=('生成规则’ for i range(num) if 'i的条件‘)

     1 a=('a' for i in range(5) if i%2)
     2 b=(i+1 for i in range(5))
     3 print(a,type(a))
     4 print(b,type(b))
     5 print(b.__next__())
     6 print(b.__next__())
     7 print(b.__next__())
     8 print(b.__next__())
     9 print(b.__next__())
    10 
    11 #运行结果
    12 <generator object <genexpr> at 0x00F9CAE0> <class 'generator'>
    13 <generator object <genexpr> at 0x00F9CC90> <class 'generator'>
    14 1
    15 2
    16 3
    17 4
    18 5
    生成式表达式

    2)yield创建生成器

    def fun_ex(a):
        yield 1
    re=fun_ex(2)
    print(re.__next__(),type(re))
    
    #运行结果
    1 <class 'generator'>

    3)生成器实现单线程的异步并发效果

    def gen_ex(a):
        while a>0:
            a-=1
            yield 1
            print('hello')
    re=gen_ex(2)
    print(re.__next__())
    print('中断打印')
    print(re.__next__())
    
    #运行结果
    1
    中断打印
    hello
    1

    生成器是每次调用返回一次数据,所以可以在中途插入其他操作,形成一种异步效果,如例子中先来个“中断打印”

    4)生成器中的send()方法使用

    def gen_ex(a):
        while a>0:
            a-=1
            b=yield
            print(b)
    re=gen_ex(5)
    re.__next__()
    re.send(5)
    print('中断打印')
    re.send(6)
    
    #运行结果
    5
    中断打印
    6

    send()可以给yield传参数,yield作为接收。这里yield的运行情况和return在函数上起的作用有些区别。

    如生成器使用一个__next__()方法,它会运行到yield这行,而停止。但是再使用send()方法,函数直接从yield这行开始运行,并赋值给b,然后运行下去循环一次到yield这行停止。

    3.装饰器

    装饰器的作用在于,对已有函数,在不改变它内在封装上扩展它的功能。如:

    def start(func):
        def inner(arg):
            print('how are you!')
            func(arg)
        return inner
    
    @start
    def user(arg):
        print('hello %s'%arg)
    
    # user=start(user)              #这条功能和@start一样
    user('olive')
    
    #运行结果
    how are you!
    hello olive

     上例中,start就是实现装饰器功能,@start和user=start(user)一样的功能效果,@start更具有装饰器特征。

    上面是传单参数装饰器,也可以多参数或n参数,如:

     1 def start(func):
     2     def inner(*args,**kwargs):
     3         print('how are you!')
     4         func(*args,**kwargs)
     5     return inner
     6 
     7 @start
     8 def user(*args,**kwargs):
     9     print('hello ' )
    10 
    11 user('olive','a','b')
    12 
    13 #运行结果
    14 how are you!
    15 hello 
    多参数装饰器

     装饰器可以写一个装饰器框架,把装饰器当函数调用。

  • 相关阅读:
    freetype2 下载编译以及测试代码
    mysql报错:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
    git diff左右对比
    AcWing 1304. 佳佳的斐波那契
    AcWing 1303. 斐波那契前 n 项和
    AcWing 1305. GT考试
    AcWing 1312. 序列统计
    AcWing 1310. 数三角形
    AcWing 1315. 网格
    AcWing 1309. 车的放置
  • 原文地址:https://www.cnblogs.com/olivexiao/p/6551017.html
Copyright © 2020-2023  润新知