zoukankan      html  css  js  c++  java
  • 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 
    多参数装饰器

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

  • 相关阅读:
    jquery 实现 html5 placeholder 兼容password密码框
    php返回json的结果
    使用PHP读取远程文件
    Sharepoint 自定义字段
    Sharepoint 中新增 aspx页面,并在页面中新增web part
    【转】Sharepoint 2010 配置我的站点及BLOG
    JS 实现 Div 向上浮动
    UserProfile同步配置
    【转】Import User Profile Photos from Active Directory into SharePoint 2010
    Sharepoint 2010 SP1升级后 FIMSynchronizationService 服务无法开启
  • 原文地址:https://www.cnblogs.com/olivexiao/p/6551017.html
Copyright © 2011-2022 走看看