有參裝飾器、迭代器

一、有參裝飾器python

 

'''

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

 

 

 

二、迭代器mysql

 

'''
一、什麼是迭代器
    迭代器即迭代取值的工具
    迭代:
        迭代是一個重複的過程,每一次重複都是基於上一次的結果而來的

        單純的重複並非迭代
        while True:
            print('1111')   #單純的重複沒有基於上一次的結果

        迭代:
        l=['a','b','c']

        def iterator(item):
            i=0
            while i < len(item):
                print(l[i])
                i+=1


二、 爲何要有迭代器
    基於索引的迭代器取值方式只適用於列表、元組、字符串類型
    而對於沒有索引的字典、集合、文件,則不在適用
    因此必須找到一種通用的而且不依賴於索引的迭代器取值方式=》迭代器

    迭代器適用於可迭代的類型

三、如何用迭代器


'''
# 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__方法獲得的就是內置的迭代器對象
# 文件對象--------------------------自己就是迭代器對象

#強調:
#一、迭代器對象必定是可迭代的對象,反之則否則



# 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
#


#總結迭代器對象的優缺點:
#優勢:
#一、提供了一種通用的、能夠不依賴索引的迭代取值方式
#二、迭代器對象更加節省內存
# 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))


# 缺點:
#一、迭代器的取值不如按照索引的方式更靈活,由於它只能日後取不能往前退
#二、沒法預測迭代器值的個數
# 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\n', '2222222222222\n', '33333\n', '4444\n', '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]
相關文章
相關標籤/搜索