zoukankan      html  css  js  c++  java
  • 函数(五)——装饰器,迭代器

    今日内容概要:

    一、嵌套三层函数的装饰器(了解)

    二、迭代器(掌握)

    内容详解:

    一、嵌套三层函数的装饰器

    #分析
    import time
    def outter1(func):
        def wrapper(*args, **kwargs):
            start = time.time()
            res = func(*args, **kwargs)
            stop = time.time()
            print(stop - start)
            return res
    
        return wrapper
    
    # @函数的内存地址1(1,2,3,4,5)  # 函数的内存地址(index)
    def index(x, y):
        print('index===>', x, y)
        
    @outter1
    def home(name):
        print('home====>', name)
    引出两个点:
    (1)可以通过闭包的方式为函数体传参,可以包一层,也可以包两层
    (2)@后跟的必须是一个函数的内存地址
    @函数的内存地址(1,2,3) 是可以的,但是前提是调用函数"函数的内存地址(1,2,3)"的
    返回值必须是一个函数的内存地址
    #示范一:
    def outter(func):
        def wrapper(*args, **kwargs):
            inp_name=input("please input your name: ").strip()
            inp_pwd=input("please input your password: ").strip()
            with open('user.db',mode='rt',encoding='utf-8') as f:
                for line in f:
                    name_db,pwd_db=line.strip('
    ').split(':')
                    if inp_name == name_db and inp_pwd == pwd_db:
                        print('login successful')
                        res = func(*args, **kwargs)
                        return res
                else:
                    print("账号或密码错误")
    
        return wrapper
    
    @outter
    def index(x, y):
        print('index===>', x, y)
    
    
    index(1, 2)
    #示范二(完善):
    # ldap
    # mysql
    # file
    
    def outter2(mode):
        def outter(func):
            def wrapper(*args, **kwargs):
                inp_name=input("please input your name: ").strip()
                inp_pwd=input("please input your password: ").strip()
                if mode == "file":
                    print('认证来源=====>file')
                    with open('user.db',mode='rt',encoding='utf-8') as f:
                        for line in f:
                            name_db,pwd_db=line.strip('
    ').split(':')
                            if inp_name == name_db and inp_pwd == pwd_db:
                                print('login successful')
                                res = func(*args, **kwargs)
                                return res
                        else:
                            print("账号或密码错误")
                elif mode == "ldap":
                    print('认证来源=====>ldap')
                elif mode == "mysql":
                    print('认证来源=====>mysql')
                else:
                    print("未知的认证来源")
            return wrapper
        return outter
    
    outter=outter2(mode="mysql")
    
    @outter # index=outter(index) ==>index=wrapper
    def index(x, y):
        print('index===>', x, y)
    
    
    index(1, 2) # wrapper(1,2)
    #示范三(改进):
    def outter2(mode):
        def outter(func):
            def wrapper(*args, **kwargs):
                inp_name=input("please input your name: ").strip()
                inp_pwd=input("please input your password: ").strip()
                if mode == "file":
                    print('认证来源=====>file')
                    with open('user.db', mode='rt', encoding='utf-8') as f:
                        for line in f:
                            name_db,pwd_db=line.strip('
    ').split(':')
                            if inp_name == name_db and inp_pwd == pwd_db:
                                print('login successful')
                                res = func(*args, **kwargs)
                                return res
                        else:
                            print("账号或密码错误")
                elif mode == "ldap":
                    print('认证来源=====>ldap')
                elif mode == "mysql":
                    print('认证来源=====>mysql')
                else:
                    print("未知的认证来源")
            return wrapper
        return outter
    
    @outter2(mode="mysql") # index=outter(index) ==>index=wrapper
    def index(x, y):
        print('index===>', x, y)
    
    
    index(1, 2) # wrapper(1,2)

    有参装饰器(三层装饰器)模板!!!

    def outter2(x,y,z):
        def outter1(func):
            def wrapper(*args ,**kwargs):
                res =func(*args ,**kwargs)
                return res
            return wrapper
        return outter1
    
    
    
    @outter2(1,2,3) # index=outter1(index)
    def index():
        pass
    
    index() # wrapper()
            index() # wrapper()

    二、迭代器

    1、迭代器

    迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的
     注意:迭代不是单纯的重复
    迭代器是一种迭代取值的工具,这种取值方式是通用,不依赖于索引
    基于同一个迭代器取值,取干净了就再也没有了
    str ===》索引
    list ===》索引
    tuple ===》索引
    t = (1111, 222, 333, 444, 555, 666)
    i = 0
    while i < len(t):
    print(t[i])
    i += 1

    dict ===》key
    set ===》既没有key也没有索引
    f文件对象==》既没有key也没有索引
    python为上述类型都内置了__iter__方法
    s = "hello"
    ll = [111, 222, 333]
    t = (1111, 222, 333, 444, 555, 666)
    d = {"k1": 111, "k2": 222, "k3": 3333}
    s1 = {'a', 'b', 'c'}
    f = open(r'user.db', mode='rt', encoding='utf-8')
    f.close()
    
    调用__iter__方法得到的返回值就是对应的迭代器
    res = d.__iter__()  # res=iter(d)
    print(res) # res是迭代器
    a = res.__next__()  # a=next(res)
    b = res.__next__()  # b=next(res)
    c = res.__next__()  # c=next(res)
    d = res.__next__()  # StopIteration
    print(c)
    
    d = {"k1": 111, "k2": 222, "k3": 3333}
    
    iter_d = iter(d)
    
    while True:
        try:
            print(next(iter_d))
        except StopIteration:
            break
    2、可迭代对象:有__iter__内置方法的对象都是可迭代的对象,str、list、tuple、dict、set、文件对象
    ps:可迭代对象.__iter__()返回的是迭代器对象

    3、迭代器对象:
    1、有__next__方法
    2、有__iter__方法,调用迭代器的__iter__方法得到的就是迭代器自己
    ps:迭代器对象之所内置__iter__方法是为了符合for循环的工作步骤
    f = open(r'user.db', mode='rt', encoding='utf-8')
    # line=f.__next__()
    # print(line)
    # line=f.__next__()
    # print(line)
    # for line in f:
    #     print(line)
    
    f.close()
    # line=f.__next__() # 报错
    d = {"k1": 111, "k2": 222, "k3": 3333}
    res=d.__iter__()
    
    print(res)
    print(res.__iter__())
    print(res.__iter__() is res)
    print(res.__iter__().__iter__().__iter__() is res)

    4、for循环的工作原理=》迭代器循环

    for循环的工作步骤:
    (1)调用in后的对象的__iter__方法,得到对应的迭代器
    (2)k=next(迭代器),然后执行一次循环
    (3)循环往复,直到把迭代器的值取干净了,抛出异常,for循环会自动捕捉异常,结束循环
    d = {"k1": 111, "k2": 222, "k3": 3333}
    
    for k in d:
        print(k)

    5、总结迭代器:

    优点:
    1、不依赖索引,是一种通用的取值方式
    2、节省内存
    d = {"k1": 111, "k2": 222, "k3": 3333}
    iter_d=iter(d)
    
    next(iter_d)
    缺点:
    1、不能取指定位置的值
    2、不能预估值的个数,无法统计长度
    ll = [111, 222, 333]
    print(ll[2])
    
    iter_ll=iter(ll)
    next(iter_ll)
    next(iter_ll)
    print(next(iter_ll))
  • 相关阅读:
    Spring Boot第四弹,一文教你如何无感知切换日志框架?
    Spring Boot 第三弹,一文带你了解日志如何配置?
    UVa 1625
    UVa 11584
    UVa 11400
    UVa 12563
    UVa 116
    UVa 1347
    UVa 437
    UVa 1025
  • 原文地址:https://www.cnblogs.com/guojieying/p/13179332.html
Copyright © 2011-2022 走看看