• 有参装饰器、迭代器


    1、有参装饰器

    '''
    
    import time
    current_user={'user':None}
    def deco(func):
        def wrapper(*args,**kwargs):
            if current_user['user']:
                #已经登陆过
                res = func(*args, **kwargs)    #用户已经登录直接调用被装饰的函数,不需要重复进行登录
                return res
            user=input('username>>: ').strip()
            pwd=input('password>>: ').strip()
            if user == 'egon' and pwd == '123':
                print('login successful')
                # 记录用户登陆状态
                current_user['user']=user        #登录成功记录用户的登录状态,然后调用被装饰的函数
                res=func(*args,**kwargs)
                return res
            else:
                print('user or password error')
        return wrapper
    
    @deco
    def index():
        print('welcome to index page')
        time.sleep(1)
    
    @deco
    def home(name):
        print('welecome %s to home page' %name)
        time.sleep(0.5)
    
    
    index()
    home('egon')
    '''
    
    # def f1():
    #     x=1
    #     def f2():          #装饰器外在套一层函数,通常最多套三层
    #         def f3():
    #             print(x)
    #         return f3
    #     return f2
    #
    # f2=f1()
    #
    # f3=f2()
    #
    # f3()
    
    
    
    
    import time
    current_user={'user':None}                          #记录用户的登录状态
    def auth(engine='file'):                            #接收函数体内部需要外部传入的参数
        def deco(func):                                 #func接收被装饰的函数不能改
            def wrapper(*args,**kwargs):                #wrapper(*args,**kwargs)接收被装饰函数的的参数
                if current_user['user']:                #记录用户的登录状态,判断用户是否已经登录
                    #已经登陆过
                    res = func(*args, **kwargs)         #用户已经登录,则会直接调用被装饰的函数
                    return res                          #拿到被装饰函数的返回值,没有返回值则返回None
                user=input('username>>: ').strip()
                pwd=input('password>>: ').strip()
                if engine == 'file':                    #engine即为需要最外层函数传入的值,否则会报错
                    # 基于文件的认证
                    if user == 'egon' and pwd == '123':
                        print('login successful')
                        # 记录用户登陆状态
                        current_user['user']=user       #记录用户的登录成功后的状态
                        res=func(*args,**kwargs)        #登录成功后调用被装饰的函数
                        return res                      #拿到被装饰函数的返回值
                    else:
                        print('user or password error')
                elif engine == 'mysql':
                    print('基于mysql的认证')
                elif engine == 'ldap':
                    print('基于ldap的认证')
                else:
                    print('无法识别认证来源')
            return wrapper
        return deco
    
    @auth(engine='file') # @deco #index=deco(index) #index=wrapper
    def index():
        print('welcome to index page')
        time.sleep(1)
    
    @auth(engine='file')
    def home(name):
        print('welecome %s to home page' %name)
        time.sleep(0.5)
    
    
    index()
    home('egon')

    2、迭代器

    '''
    1、什么是迭代器
        迭代器即迭代取值的工具
        迭代:
            迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的
    
            单纯的重复并不是迭代
            while True:
                print('1111')   #单纯的重复没有基于上一次的结果
    
            迭代:
            l=['a','b','c']
    
            def iterator(item):
                i=0
                while i < len(item):
                    print(l[i])
                    i+=1
    
    
    2、 为什么要有迭代器
        基于索引的迭代器取值方式只适用于列表、元组、字符串类型
        而对于没有索引的字典、集合、文件,则不在适用
        所以必须找到一种通用的并且不依赖于索引的迭代器取值方式=》迭代器
    
        迭代器适用于可迭代的类型
    
    3、如何用迭代器
    
    
    '''
    # l=['a','b','c']
    # i=0
    # while i < len(l):            #使用while条件循环,每次基于上一次的结果而来,所以是迭代
    #     print(l[i])
    #     i+=1
    
    # l = ['a', 'b', 'c']
    # s='hello'
    #
    # def iterator(item): #item='hello'     #将重迭代的过程,定义成一个函数,每次取不同数据类型的值,只需要传参调用即可
    #     i = 0
    #     while i < len(item):
    #         print(item[i])
    #         i += 1
    # # iterator(l)                        #将列表当做参数传入调用
    # iterator(s)                          #将字符串当做参数传入调用
    
    
    # 可迭代的对象:在python中但凡内置有__iter__方法的对象都是可迭代的对象
    # 字符串、列表、元组、字典、集合、文件都是可迭代的对象
    # num1=10
    # num2=10.1
    # s1='hello'
    # l=[1,2,3]
    # t=(1,2,3)
    # d={'x':1}
    # s2={1,2,3}
    # f=open('a.txt','w')
    #
    # s1.__iter__               #以下数据类型及文件均内置有__iter__,所以都是可迭代对象
    # l.__iter__
    # t.__iter__
    # d.__iter__
    # s2.__iter__
    # f.__iter__
    
    
    #
    #
    # 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象
    #执行可迭代对象的__iter__方法得到的就是内置的迭代器对象
    # 文件对象--------------------------本身就是迭代器对象
    
    #强调:
    #1、迭代器对象一定是可迭代的对象,反之则不然
    
    
    
    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}
    # info_iter=info.__iter__()    #---------执行__iter__()方法。得到的是迭代器对象
    # print(info_iter)           #---------<dict_keyiterator object at 0x0000010BDC4110E8>字典的key值迭代器对象
    
    # res1=info_iter.__next__()    #---------迭代器对象执行__next__()方法,取出可迭代对象中的一个值
    # print(res1)                  #---------name
    
    # res2=info_iter.__next__()
    # print(res2)                  #---------age
    #
    # res3=info_iter.__next__()
    # print(res3)                #---------is_beautiful
    #
    # res4=info_iter.__next__()
    # print(res4)                #---------sex
    #
    # info_iter.__next__() # 一旦迭代器取值取干净,再继续取就会抛出StopIteration
    
    
    
    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}
    # # info=[1,2,3,4,5]
    # info_iter=info.__iter__()
    # while True:
    #     try:
    #         print(info_iter.__next__())
    #     except StopIteration:            #判断抛出的异常是不是StopIteration,是则执行break
    #         break
    
    
    #for循环:迭代器循环
    # info={'name':'egon','age':18,'is_beautiful':True,'sex':'male'}
    #in后跟的一定要是可迭代的对象
    # for k in info: # info_iter=info.__iter__()
    #     print(k)
    
    # f=open('a.txt','r')
    # for k in f:
    #     print(k)
    
    
    #基于for循环,我们可以完全不再依赖索引去取值了
    # dic={'a':1,'b':2,'c':3}
    # for k in dic:
    #     print(dic[k])
    
    #for循环的工作原理
    #1:执行in后对象的dic.__iter__()方法,得到一个迭代器对象iter_dic
    #2: 执行next(iter_dic),将得到的值赋值给k,然后执行循环体代码
    #3: 重复过程2,直到捕捉到异常StopIteration,结束循环
    
    
    # 总结:
    # 迭代器对象:指的是既内置有__iter__方法,又内置有__next__方法的对象
    # 执行迭代器对象的__next__得到的是迭代器的下一个值
    # 执行迭代器对象的__iter__得到的仍然是迭代器本身
    
    # iter_info=info.__iter__()
    # # print(iter_info)
    # print(iter_info is iter_info.__iter__() is iter_info.__iter__().__iter__().__iter__().__iter__().__iter__())    #True
    #
    
    
    #总结迭代器对象的优缺点:
    #优点:
    #1、提供了一种通用的、可以不依赖索引的迭代取值方式
    #2、迭代器对象更加节省内存
    # f=open('movie.tar.gz','rb')
    # f.__ next__()
    # f=open('db.txt','rt',encoding='utf-8')
    #
    # print(f.__next__())
    # print(f.__next__())
    # print(next(f)) #f.__next__()
    
    # s='hello'
    # print(s.__len__())
    # print(len(s))
    # s.__iter__()
    # print(iter(s))
    
    
    # 缺点:
    #1、迭代器的取值不如按照索引的方式更灵活,因为它只能往后取不能往前退
    #2、无法预测迭代器值的个数
    # names=['egon','alex_SB','wxx_SB']       #取出列表中的第二个值,只能一个一个的取,也不能统计出列表的长度,只有取完再取的时候才会抛出异常
    # iter_names=iter(names)
    # print(next(iter_names))
    # print(next(iter_names))
    #
    # iter_names=iter(names)
    # print(next(iter_names))
    # print(next(iter_names))
    # # print(next(iter_names))
    #
    # print(names[1])                       #而使用索引则可以很方面的就取出列表中的第二个值
    # print(names[1])
    
    
    
    # s=set('helllllo')     #将字符串转换成集合底层原理:就是先把字符串执行__iter__得到迭代器对象,迭代器对象在执行__next__方法,将值取出来放到集合中,直到值被取干净
    # print(s)
    
    
    # for i in 10:         #10不可迭代对象,底层原理走不通所以会报错,TypeError: 'int' object is not iterable
    #     pass
    
    # list(10)          #list底层原理也是for循环,所以放10也会包同样的错误,TypeError: 'int' object is not iterable
    
    # names=['a','b','c','d']
    # iter_names=iter(names)        #names.__iter__()可以改写成iter(names)两者是等价的
    #
    # l1=list(iter_names)          #将迭代器对象循环放入得到列表中
    # print(l1)                    #['a', 'b', 'c', 'd']
    #
    # l2=list(iter_names)          #迭代器对象值已经全部放入到列表中,所以已经别取干净了,此时的列表为空列表
    # print(l2)                    #[]
    
    # f=open('db.txt','rt',encoding='utf-8')
    #
    # print(list(f))       #文件本身就是迭代器对象,所以第一次已经把文件中的值全部取干净了,['11111111111111111
    ', '2222222222222
    ', '33333
    ', '4444
    ', '55555']
    # print(list(f))       #[]   #迭代器对象已经为空,所以得到的列表也均为空列表
    # print(list(f))       #[]
    # print(list(f))       #[]
    # print(list(f))       #[]
    
    
    # l1=[1,2,3,]
    # diedaiqi=l1.__iter__()
    # print(list(l1))           #l1均为迭代器对象,循环将值放入到列表中的列表都会有值,[1, 2, 3]
    # print(list(l1))           #[1, 2, 3]
    # print(list(l1))           #[1, 2, 3]
    # print(list(l1))           #[1, 2, 3]
    # print(list(l1))           #[1, 2, 3]
    # print(list(l1))           #[1, 2, 3]
  • 相关阅读:
    mysql The server time zone value 'xxx' is unrecognized
    mysql Public Key Retrieval is not allowed
    mysql Unable to load authentication plugin 'caching_sha2_password'.
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
    ZOJ Problem Set
  • 原文地址:https://www.cnblogs.com/sui776265233/p/9173557.html
Copyright © 2020-2023  润新知