• Python高手之路【四】python函数装饰器,迭代器


    def outer(func):
        def inner():
            print('hello')
            print('hello')
            print('hello')
            r = func()
            print('end')
            print('end')
            print('end')
        return inner
    @outer
    def f1():
        print("f1 called")
    # 1:执行outer函数,并且将其下面的函数名(这里就是f1函数),当做参数传递给outer函数
    # 2:将outer的返回值重新赋值给f1=outer的返回值
    # 3:新f1函数 = inner
    # 装饰器的本质就是将原函数封装到一个新函数里,让原函数执行新函数里的内容
    f1()

    输出结果为:

    hello
    hello
    hello
    f1 called
    end
    end
    end

    只要函数应用装饰器,那么函数就被重新定义,重新定义为装饰器的内层函数

    装饰器含两个参数的函数:

    def outer(func):
        def inner(a1,a2):
            print('123')
            ret = func(a1,a2)
            print('456')
            return ret
        return inner
    @outer
    def index(a1,a2):
        print('234')
        return a1+a2
    index(1,2)

    装饰器含N个参数的函数:

    def outer(func):
        def inner(*arg,**kwargs):
            print('begin')
            ret = func(*arg,**kwargs)
            print('end')
            return ret
        return inner

    多个装饰器装饰同一个函数:

    def outer_0(func):
        def inner(*arg,**kwargs):
            print('top')
            ret = func(*arg,**kwargs)
            return ret
        return inner
    
    def outer(func):
        def inner(*arg,**kwargs):
            print('begin')
            ret = func(*arg,**kwargs)
            print('end')
            return ret
        return inner
    
    @outer_0
    @outer
    def index(a1,a2):
        print('index')
        return a1+a2
    index(1,2)

    迭代器

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

    特点:

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

    生成一个迭代器:

    >>> a = iter([1,2,3,4,5])
    >>> a
    <list_iterator object at 0x101402630>
    >>> a.__next__()
    1
    >>> a.__next__()
    2
    >>> a.__next__()
    3
    >>> a.__next__()
    4
    >>> a.__next__()
    5
    >>> a.__next__()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    

    Repeated calls to the iterator’s __next__() method (or passing it to the built-in function next()) return successive items in the stream. When no more data are available a StopIteration exception is raised instead. At this point, the iterator object is exhausted and any further calls to its __next__() method just raise StopIteration again.

    生成器generator

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

    代码:

    def cash_out(amount):
        while amount >0:
            amount -= 1
            yield 1<br>        print("擦,又来取钱了。。。败家子!") 
    ATM = cash_out(5) 
    print("取到钱 %s 万" % ATM.__next__())
    print("花掉花掉!")
    print("取到钱 %s 万" % ATM.__next__())
    print("取到钱 %s 万" % ATM.__next__())
    print("花掉花掉!")
    print("取到钱 %s 万" % ATM.__next__())
    print("取到钱 %s 万" % ATM.__next__())
    print("取到钱 %s 万" % ATM.__next__()) #到这时钱就取没了,再取就报错了
    print("取到钱 %s 万" % ATM.__next__())
    

    作用:

    这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

    另外,还可通过yield实现在单线程的情况下实现并发运算的效果

    import time
    def consumer(name):
        print("%s 准备吃包子啦!" %name)
        while True:
           baozi = yield
     
           print("包子[%s]来了,被[%s]吃了!" %(baozi,name))
     
    def producer(name):
        c = consumer('A')
        c2 = consumer('B')
        c.__next__()
        c2.__next__()
        print("老子开始准备做包子啦!")
        for i in range(10):
            time.sleep(1)
            print("做了2个包子!")
            c.send(i)
            c2.send(i)
     
    producer("alex")
    
  • 相关阅读:
    Android后台保活实践总结:即时通讯应用无法根治的“顽疾”
    新手入门:史上最全Web端即时通讯技术原理详解
    【原创】NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
    【原创】NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
    【原创】NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
    【原创】NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
    爱奇艺技术分享:轻松诙谐,讲解视频编解码技术的过去、现在和将来
    网络编程懒人入门(十二):快速读懂Http/3协议,一篇就够!
    美团点评的移动端网络优化实践:大幅提升连接成功率、速度等
    IM开发宝典:史上最全,微信各种功能参数和逻辑规则资料汇总
  • 原文地址:https://www.cnblogs.com/ginvip/p/6253993.html
Copyright © 2020-2023  润新知