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)"的
    返回值必须是一个函数的内存地址

    2.1示范一:

    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)
    

    2.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)
    
    
    

    2.3示范三:

    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)
    

    一、迭代器

    迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的
    注意:迭代不是单纯的重复

    迭代器是一种迭代取值的工具,这种取值方式是通用,不依赖于索引

    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
    

    可迭代的对象:

    有__iter__内置方法的对象都是可迭代的对象,str、list、tuple、dict、set、文件对象
    ps:可迭代对象.iter()返回的是迭代器对象

    迭代器对象:

    ​ 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)
    

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

    d = {"k1": 111, "k2": 222, "k3": 3333}
    
    for k in d:
        print(k
    

    )

    for循环的工作步骤
    1、调用in后的对象的__iter__方法,得到对应的迭代器
    2、k=next(迭代器),然后执行一次循环
    3、循环往复,知道把迭代器的值取干净了,抛出异常,for循环会自动捕捉异常,结束循环

    三,总结迭代器:

    优点:

    1、不依赖索引,是一种通用的取值方式
    2、节省内存

    d = {"k1": 111, "k2": 222, "k3": 3333}
    iter_d=iter(d)
    
    next(iter_d)
    

    缺点:

    1、不能取指定位置的值

    ll = [111, 222, 333]
    print(ll[2])
    
    iter_ll=iter(ll)
    next(iter_ll)
    next(iter_ll)
    print(next(iter_ll))
    

    2、不能预估值的个数,无法统计长度

    2、不能预估值的个数,无法统计长度

  • 相关阅读:
    Thinking in Java Reading Note(9.接口)
    Thinking in java Reading Note(8.多态)
    Thinking in Java Reading Note(7.复用类)
    SQL必知必会
    Thinking in Java Reading Note(5.初始化与清理)
    Thinking in Java Reading Note(2.一切都是对象)
    鸟哥的Linux私房菜笔记(1.基础)
    Thinking in Java Reading Note(1.对象导论)
    CoreJava2 Reading Note(2:I/O)
    CoreJava2 Reading Note(1:Stream)
  • 原文地址:https://www.cnblogs.com/lgh8023/p/13176770.html
Copyright © 2011-2022 走看看