• Python初探第二篇-装饰器和迭代器,生成器


    一,装饰器

      1,概念

      装饰器就是给已有的模块添加新的功能,如登录验证功能,运行时间功能等。本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
      强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
      装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能

      2,理论基础

      要想实现装饰器的功能,我们需要三个理论基础:函数闭包+函数嵌套+高阶函数。我们通过为如下模块加入统计运行时间的装饰器来讲解如何使用

    import time
    def test_func():
        for i in range(5):
            time.sleep(0.5)

      3,推导

      首先我们知道要知道函数的运行时间,只需要在函数前后加上当前时间,通过差值就能计算出来。因此我们可以定义一个模块,并传入所求的函数的函数地址,即高阶函数。

      模块中包含此函数的调用和统计时间的功能

    import time
    
    def test_func():
        for i in range(5):
            time.sleep(0.5)
    
    def decorate(func):
        start_time = time.time()
        func()
        end_time = time.time()
        print(end_time-start_time)
    
    decorate(test_func)   #2.5s

      这样就实现了统计时间的功能,但是却修改了函数的调用逻辑,因此进一步思考,我们可以在装饰器函数内定义函数,并在此函数内调用被统计函数,即函数嵌套,并返回

           代码 如下:

    import time
    def test_func():
        for i in range(5):
            time.sleep(0.5)
    def decorate(func):
        def count_time():
            start_time = time.time()
            func()
            end_time = time.time()
            print(end_time-start_time)
        return count_time
    test_func = decorate(test_func)
    test_func()

    而python给我们提供了装饰器语法:

    import time
    
    def decorate(func):
        def count_time():
            start_time = time.time()
            func()
            end_time=time.time()
            print(end_time-start_time)
        return count_time
    
    @decorate 
    def test_func():
        for i in range(5):
            time.sleep(0.5)
    
    test_func()

     上面就实现了一个简单的装饰器,可根据需求来增加它的功能,如传入参数,返回值等。

    二,迭代器

      1,概念

      迭代器(iteretor)是一种遍历容器所有或者部分元素的方法,相当于一个复杂的指针,能够遍历复杂的数据结构,一个容器也应该提供它自己的迭代器。

      2,迭代器对象与可迭代对象

       迭代器对象:即对象能够提供遍历它的方法,像是迭代器的一种具体表现,在Python中迭代器对象能够提供__iter__和__next__方法来得到容器中下一个元素的值。

       可迭代对象:即对象提供__iter__方法,使用该方法后得到迭代器对象,如字符串,列表元组

    li=[1,2,3,4,5]
    li=li.__iter__()  # 可迭代对象转化成迭代器对象
    print(li.__next__())  # 1

      3,使用方法  

    dic = {"a": 1, "e": 4, "b": 2, "c": 3, "d": 4}
    iter_dic = dic.__iter__()
    # while True:
    try:
        print(next(iter_dic))   #"a" "e" "b".....
    except StopIteration:     #需要手动捕捉异常
        break

      而我们可以借助Python中强大的for循环机制来循环遍历容器

      4,for循环

    #基于for循环,我们可以完全不再依赖索引去取值了
    dic = {'a':1,'b':2,'c':3}
    for k in dic:
        print(dic[k])
    
    #for循环的工作原理
    #1:执行in后对象的dic.__iter__()方法,迭代器对象.__iter,返回对象本身。得到一个迭代器对象iter_dic
    #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    #3: 重复过程2,直到捕捉到异常StopIteration,结束循环

     三,生成器

      Python使用生成器能够实现延时操作,何谓延时操作,即需要结果时就产生结果,不需要时就不产生。提供生成器对象有两种方式:

      1,生成器函数:和常规的函数定义一样只不过不用return,而是使用yield来返回结果。一次只返回一个结果,在每个结果中间,挂起函数状态,以便下次继续返回。

      2,生成器表达式:生成一个生成器对象,按需产生结果,就是迭代的时候产生具体的值。

        1,生成器函数  

    def gensquares(n):
        for i in range(n):
            yield i ** 2
    
    
    obj = gensquares(5)
    print(obj)  # <generator object gensquares at 0x00000000021E55C8>
    print(next(obj))  # 0
    print(next(obj))  # 1
    print(next(obj))  # 4

      2,生成器表达式

    li = []
    for i in range(5):
        name = "name%d" % i
        li.append(name)
    print(li)  # ['name0', 'name1', 'name2', 'name3', 'name4']
    # 列表推导
    li = ["name%d" % i for i in range(5)]
    print(li)  # ['name0', 'name1', 'name2', 'name3', 'name4']
    # 简洁了许多
    
    # 生成器表达式
    gens = ("name%d" % i for i in range(5))
    print(gens)  # <generator object <genexpr> at 0x00000000028655C8>
    print(next(gens))  # name0
    print(next(gens))  # name1
    print(next(gens))  # name2
    #生成器对象就是迭代器对象

         使用生成器的好处数据不会直接加载到内存,在数据量很大的情况下作用很大。比如使用内置函数如下

    #print(sum([i for i in range(100000000)])) #提示计算机内存不足,程序崩溃
    print(sum((i for i in range(1000000000)))) #程正常运行

        注意事项:生成器对象是一种迭代器对象,它们都只能遍历一次,而可迭代对象可以多次遍历。

  • 相关阅读:
    linux下源码安装python3
    FTP 命令
    Linux Shell数值比较和字符串比较及相关
    mount umount sort du tar
    linux 自动检查ssh脚本
    删除linux访问记录(message删不了)
    h3c 备份脚本
    linux 批量scp 脚本
    Linux 删除几天前的文件脚本
    博达交换机镜像检查,镜像丢失自动添加脚本
  • 原文地址:https://www.cnblogs.com/ifyoushuai/p/8970244.html
Copyright © 2020-2023  润新知